tizen 2.3 release
[framework/api/application.git] / preference / preference.c
1 /*
2  * Copyright (c) 2011 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 <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <sqlite3.h>
23
24 #include <dlog.h>
25
26 #include <app_common.h>
27 #include <app_internal.h>
28 #include <app_preference.h>
29 #include <app_preference_internal.h>
30
31 #ifdef LOG_TAG
32 #undef LOG_TAG
33 #endif
34
35 #define LOG_TAG "CAPI_APPFW_PREFERENCE"
36 #define DBG_MODE (1)
37
38 static sqlite3 *pref_db = NULL;
39 static bool is_update_hook_registered = false;
40 static pref_changed_cb_node_t *head = NULL;
41
42 static void _finish(void *data)
43 {
44         if (pref_db != NULL)
45         {
46                 sqlite3_close(pref_db);
47                 pref_db = NULL;
48         }
49 }
50
51 static int _busy_handler(void *pData, int count)
52 {
53         if(5 - count > 0) {
54                 LOGD("Busy Handler Called! : PID(%d) / CNT(%d)\n", getpid(), count+1);
55                 usleep((count+1)*100000);
56                 return 1;
57         } else {
58                 LOGD("Busy Handler will be returned SQLITE_BUSY error : PID(%d) \n", getpid());
59                 return 0;
60         }
61 }
62
63 static int _initialize(void)
64 {
65         char *data_path = NULL;
66         char db_path[TIZEN_PATH_MAX] = {0, };
67         int ret;
68         char *errmsg;
69
70         if ((data_path = app_get_data_path()) == NULL)
71         {
72                 LOGE("IO_ERROR(0x%08x) : fail to get data directory", PREFERENCE_ERROR_IO_ERROR);
73                 return PREFERENCE_ERROR_IO_ERROR;
74         }
75         snprintf(db_path, sizeof(db_path), "%s/%s", data_path, PREF_DB_NAME);
76         free(data_path);
77
78         ret = sqlite3_open(db_path, &pref_db);
79         if (ret != SQLITE_OK)
80         {
81                 LOGE("IO_ERROR(0x%08x) : fail to open db(%s)", PREFERENCE_ERROR_IO_ERROR, sqlite3_errmsg(pref_db));
82                 pref_db = NULL;
83                 return PREFERENCE_ERROR_IO_ERROR;
84         }
85
86         ret = sqlite3_busy_handler(pref_db, _busy_handler, NULL);
87         if (ret != SQLITE_OK) {
88                 LOGW("IO_ERROR(0x%08x) : fail to register busy handler(%s)\n", PREFERENCE_ERROR_IO_ERROR, sqlite3_errmsg(pref_db));
89         }
90
91         ret = sqlite3_exec(pref_db, "CREATE TABLE IF NOT EXISTS pref ( pref_key TEXT PRIMARY KEY, pref_type TEXT, pref_data TEXT)",
92                        NULL, NULL, &errmsg);
93         if (ret != SQLITE_OK)
94         {
95                 LOGE("IO_ERROR(0x%08x) : fail to create db table(%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
96                 sqlite3_free(errmsg);
97                 sqlite3_close(pref_db);
98                 pref_db = NULL;
99                 return PREFERENCE_ERROR_IO_ERROR;
100         }
101
102         app_finalizer_add(_finish, NULL);
103
104         return PREFERENCE_ERROR_NONE;
105 }
106
107 static int _write_data(const char *key, const char *type, const char *data)
108 {
109         int ret;
110         char *buf = NULL;
111         bool exist = false;
112         sqlite3_stmt *stmt;
113
114         if (key == NULL || key[0] == '\0'  || data == NULL)
115         {
116                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
117                 return PREFERENCE_ERROR_INVALID_PARAMETER;
118         }
119
120         /* insert data or update data if data already exist */
121         ret = preference_is_existing(key, &exist);
122         if (ret != PREFERENCE_ERROR_NONE)
123         {
124                 return ret;
125         }
126
127         // to use sqlite3_update_hook, we have to use INSERT/UPDATE operation instead of REPLACE operation
128         if (exist)
129         {
130                 buf = sqlite3_mprintf("UPDATE %s SET %s=?, %s=? WHERE %s=?;",
131                                                                 PREF_TBL_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME, PREF_F_KEY_NAME);
132         }
133         else
134         {
135                 buf = sqlite3_mprintf("INSERT INTO %s (%s, %s, %s) values (?, ?, ?);",
136                                                                 PREF_TBL_NAME, PREF_F_KEY_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME);
137         }
138
139         if (buf == NULL)
140         {
141                 LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
142                 return PREFERENCE_ERROR_IO_ERROR;
143         }
144
145         ret = sqlite3_prepare(pref_db, buf, strlen(buf), &stmt, NULL);
146         if (ret != SQLITE_OK) {
147                 LOGE("IO_ERROR(0x%08x) : fail to prepare query (%d/%s)",
148                         PREFERENCE_ERROR_IO_ERROR,
149                         sqlite3_extended_errcode(pref_db),
150                         sqlite3_errmsg(pref_db));
151                 return PREFERENCE_ERROR_IO_ERROR;
152         }
153
154         if(exist)
155         {
156                 ret = sqlite3_bind_text(stmt, 1, type, strlen(type), SQLITE_STATIC);
157                 if(ret != SQLITE_OK) {
158                         LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)",
159                                 PREFERENCE_ERROR_IO_ERROR,
160                                 sqlite3_extended_errcode(pref_db),
161                                 sqlite3_errmsg(pref_db));
162                         sqlite3_finalize(stmt);
163                         return PREFERENCE_ERROR_IO_ERROR;
164                 }
165                 ret = sqlite3_bind_text(stmt, 2, data, strlen(data), SQLITE_STATIC);
166                 if(ret != SQLITE_OK) {
167                         LOGE("IO_ERROR(0x%08x) : fail to bind(2) query (%d/%s)",
168                                 PREFERENCE_ERROR_IO_ERROR,
169                                 sqlite3_extended_errcode(pref_db),
170                                 sqlite3_errmsg(pref_db));
171                         sqlite3_finalize(stmt);
172                         return PREFERENCE_ERROR_IO_ERROR;
173                 }
174                 ret = sqlite3_bind_text(stmt, 3, key, strlen(key), SQLITE_STATIC);
175                 if(ret != SQLITE_OK) {
176                         LOGE("IO_ERROR(0x%08x) : fail to bind(3) query (%d/%s)",
177                                 PREFERENCE_ERROR_IO_ERROR,
178                                 sqlite3_extended_errcode(pref_db),
179                                 sqlite3_errmsg(pref_db));
180                         sqlite3_finalize(stmt);
181                         return PREFERENCE_ERROR_IO_ERROR;
182                 }
183         }
184         else
185         {
186                 ret = sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC);
187                 if(ret != SQLITE_OK) {
188                         LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)",
189                                 PREFERENCE_ERROR_IO_ERROR,
190                                 sqlite3_extended_errcode(pref_db),
191                                 sqlite3_errmsg(pref_db));
192                         sqlite3_finalize(stmt);
193                         return PREFERENCE_ERROR_IO_ERROR;
194                 }
195                 ret = sqlite3_bind_text(stmt, 2, type, strlen(type), SQLITE_STATIC);
196                 if(ret != SQLITE_OK) {
197                         LOGE("IO_ERROR(0x%08x) : fail to bind(2) query (%d/%s)",
198                                 PREFERENCE_ERROR_IO_ERROR,
199                                 sqlite3_extended_errcode(pref_db),
200                                 sqlite3_errmsg(pref_db));
201                         sqlite3_finalize(stmt);
202                         return PREFERENCE_ERROR_IO_ERROR;
203                 }
204                 ret = sqlite3_bind_text(stmt, 3, data, strlen(data), SQLITE_STATIC);
205                 if(ret != SQLITE_OK) {
206                         LOGE("IO_ERROR(0x%08x) : fail to bind(3) query (%d/%s)",
207                                 PREFERENCE_ERROR_IO_ERROR,
208                                 sqlite3_extended_errcode(pref_db),
209                                 sqlite3_errmsg(pref_db));
210                         sqlite3_finalize(stmt);
211                         return PREFERENCE_ERROR_IO_ERROR;
212                 }
213         }
214
215         ret = sqlite3_step(stmt);
216         if (ret != SQLITE_DONE) {
217                 LOGE("IO_ERROR(0x%08x): fail to write data(%d/%s)",
218                         PREFERENCE_ERROR_IO_ERROR,
219                         sqlite3_extended_errcode(pref_db),
220                         sqlite3_errmsg(pref_db));
221                 sqlite3_finalize(stmt);
222                 return PREFERENCE_ERROR_IO_ERROR;
223         }
224
225         sqlite3_finalize(stmt);
226         if(buf) {
227                 sqlite3_free(buf);
228                 buf = NULL;
229         }
230
231         return PREFERENCE_ERROR_NONE;
232 }
233
234 //static int _read_data(const char *key, preference_type_e *type, char *data)
235 static int _read_data(const char *key, char *type, char *data)
236 {
237         int ret;
238         char *buf;
239         char **result;
240         int rows;
241         int columns;
242         char *errmsg;
243
244         if (key == NULL || key[0] == '\0'  || data == NULL)
245         {
246                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
247                 return PREFERENCE_ERROR_INVALID_PARAMETER;
248         }
249
250         if (pref_db == NULL)
251         {
252                 if (_initialize() != PREFERENCE_ERROR_NONE)
253                 {
254                         LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
255                         return PREFERENCE_ERROR_IO_ERROR;
256                 }
257         }
258
259         buf = sqlite3_mprintf("SELECT %s, %s, %s FROM %s WHERE %s=%Q;",
260                                                         PREF_F_KEY_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME, PREF_TBL_NAME, PREF_F_KEY_NAME, key);
261
262         if (buf == NULL)
263         {
264                 LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
265                 return PREFERENCE_ERROR_IO_ERROR;
266         }
267
268         ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
269         sqlite3_free(buf);
270         if (ret != SQLITE_OK)
271         {
272                 LOGE("IO_ERROR(0x%08x) : fail to read data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
273                 sqlite3_free(errmsg);
274                 return PREFERENCE_ERROR_IO_ERROR;
275         }
276
277         if (rows == 0)
278         {
279                 LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
280                 sqlite3_free_table(result);
281                 return PREFERENCE_ERROR_NO_KEY;
282         }
283
284         snprintf(type, 2, "%s", result[4]);                     // get type value
285         snprintf(data, BUF_LEN, "%s", result[5]);                       // get data value
286
287         sqlite3_free_table(result);
288
289         return PREFERENCE_ERROR_NONE;
290 }
291
292
293 int preference_set_int(const char *key, int value)
294 {
295         char type[2];
296         char data[BUF_LEN];
297         snprintf(type, 2, "%d", PREFERENCE_TYPE_INT);
298         snprintf(data, BUF_LEN, "%d", value);
299         return _write_data(key, type, data);
300 }
301
302 int preference_get_int(const char *key, int *value)
303 {
304         char type[2];
305         char data[BUF_LEN];
306         int ret;
307
308         if (value == NULL) {
309                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
310                 return PREFERENCE_ERROR_INVALID_PARAMETER;
311         }
312
313         ret = _read_data(key, type, data);
314         if (ret == PREFERENCE_ERROR_NONE)
315         {
316                 if (atoi(type) == PREFERENCE_TYPE_INT)
317                 {
318                         *value = atoi(data);
319                 }
320                 else
321                 {
322                         LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
323                         return PREFERENCE_ERROR_INVALID_PARAMETER;
324                 }
325         }
326
327         return ret;
328 }
329
330 int preference_set_double(const char *key, double value)
331 {
332         char type[2];
333         char data[BUF_LEN];
334         snprintf(type, 2, "%d", PREFERENCE_TYPE_DOUBLE);
335         snprintf(data, BUF_LEN, "%f", value);
336         return _write_data(key, type, data);
337 }
338
339 int preference_get_double(const char *key, double *value)
340 {
341         char type[2];
342         char data[BUF_LEN];
343
344         int ret;
345
346         if (value == NULL) {
347                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
348                 return PREFERENCE_ERROR_INVALID_PARAMETER;
349         }
350
351         ret = _read_data(key, type, data);
352         if (ret == PREFERENCE_ERROR_NONE)
353         {
354                 if (atoi(type) == PREFERENCE_TYPE_DOUBLE)
355                 {
356                         *value = atof(data);
357                 }
358                 else
359                 {
360                         LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
361                         return PREFERENCE_ERROR_INVALID_PARAMETER;
362                 }
363         }
364
365         return ret;
366 }
367
368 int preference_set_string(const char *key, const char *value)
369 {
370         char type[2];
371
372         snprintf(type, 2, "%d", PREFERENCE_TYPE_STRING);
373         if (strlen(value) > (BUF_LEN-1))
374         {
375                 LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
376                 return PREFERENCE_ERROR_INVALID_PARAMETER;
377         }
378         return _write_data(key, type, value);
379 }
380
381 int preference_get_string(const char *key, char **value)
382 {
383         char type[2];
384         char data[BUF_LEN];
385
386         int ret;
387
388         if (value == NULL)
389         {
390                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
391                 return PREFERENCE_ERROR_INVALID_PARAMETER;
392         }
393
394         ret = _read_data(key, type, data);
395         if (ret == PREFERENCE_ERROR_NONE)
396         {
397                 if (atoi(type) == PREFERENCE_TYPE_STRING)
398                 {
399                         *value = strdup(data);
400                         if (value == NULL)
401                         {
402                                 LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
403                                 return PREFERENCE_ERROR_OUT_OF_MEMORY;
404                         }
405                 }
406                 else
407                 {
408                         LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
409                         return PREFERENCE_ERROR_INVALID_PARAMETER;
410                 }
411         }
412
413         return ret;
414 }
415
416 int preference_set_boolean(const char *key, bool value)
417 {
418         char type[2];
419         char data[BUF_LEN];
420         snprintf(type, 2, "%d", PREFERENCE_TYPE_BOOLEAN);
421         snprintf(data, BUF_LEN, "%d", value);
422         return _write_data(key, type, data);
423 }
424
425 int preference_get_boolean(const char *key, bool *value)
426 {
427         char type[2];
428         char data[BUF_LEN];
429
430         int ret;
431
432         if (value == NULL) {
433                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
434                 return PREFERENCE_ERROR_INVALID_PARAMETER;
435         }
436
437         ret = _read_data(key, type, data);
438         if (ret == PREFERENCE_ERROR_NONE)
439         {
440                 if (atoi(type) == PREFERENCE_TYPE_BOOLEAN)
441                 {
442                         *value = (bool)atoi(data);
443                 }
444                 else
445                 {
446                         LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
447                         return PREFERENCE_ERROR_INVALID_PARAMETER;
448                 }
449         }
450
451         return ret;
452 }
453
454
455 // TODO: below operation is too heavy, let's find the light way to check.
456 int preference_is_existing(const char *key, bool *exist)
457 {
458         int ret;
459         char *buf;
460         char **result;
461         int rows;
462         int columns;
463         char *errmsg;
464
465         if (key == NULL  || key[0] == '\0'  || exist == NULL)
466         {
467                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
468                 return PREFERENCE_ERROR_INVALID_PARAMETER;
469         }
470
471         if (pref_db == NULL)
472         {
473                 if (_initialize() != PREFERENCE_ERROR_NONE)
474                 {
475                         LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
476                         return PREFERENCE_ERROR_IO_ERROR;
477                 }
478         }
479
480         /* check data is exist */
481         buf = sqlite3_mprintf("SELECT %s FROM %s WHERE %s=%Q;", PREF_F_KEY_NAME, PREF_TBL_NAME, PREF_F_KEY_NAME, key);
482
483         if (buf == NULL)
484         {
485                 LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
486                 return PREFERENCE_ERROR_IO_ERROR;
487         }
488
489         ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
490         sqlite3_free(buf);
491         if (ret != SQLITE_OK)
492         {
493                 LOGE("IO_ERROR(0x%08x) : fail to read data(%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
494                 sqlite3_free(errmsg);
495                 return PREFERENCE_ERROR_IO_ERROR;
496         }
497
498         if (rows > 0)
499         {
500                 *exist = true;
501         }
502         else
503         {
504                 *exist = false;
505         }
506
507         sqlite3_free_table(result);
508         return PREFERENCE_ERROR_NONE;
509 }
510
511 static pref_changed_cb_node_t* _find_node(const char *key)
512 {
513         pref_changed_cb_node_t *tmp_node;
514
515         if (key == NULL || key[0] == '\0' )
516         {
517                 return NULL;
518         }
519
520         tmp_node = head;
521
522         while (tmp_node)
523         {
524                 if (strcmp(tmp_node->key, key) == 0)
525                 {
526                         break;
527                 }
528                 tmp_node = tmp_node->next;
529         }
530
531         return tmp_node;
532 }
533
534
535 static int _add_node(const char *key, preference_changed_cb cb, void *user_data)
536 {
537         pref_changed_cb_node_t *tmp_node;
538
539         if (key == NULL  || key[0] == '\0'  || cb == NULL)
540         {
541                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
542                 return PREFERENCE_ERROR_INVALID_PARAMETER;
543         }
544
545         tmp_node = _find_node(key);
546
547         if (tmp_node != NULL)
548         {
549                 tmp_node->cb = cb;
550                 tmp_node->user_data = user_data;
551         }
552         else
553         {
554                 tmp_node = (pref_changed_cb_node_t*)malloc(sizeof(pref_changed_cb_node_t));
555                 if (tmp_node == NULL)
556                 {
557                         LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
558                         return PREFERENCE_ERROR_OUT_OF_MEMORY;
559                 }
560
561                 tmp_node->key = strdup(key);
562                 if (tmp_node->key == NULL)
563                 {
564                         free(tmp_node);
565                         LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
566                         return PREFERENCE_ERROR_OUT_OF_MEMORY;
567                 }
568
569                 if (head != NULL)
570                         head->prev = tmp_node;
571                 tmp_node->cb = cb;
572                 tmp_node->user_data = user_data;
573                 tmp_node->prev = NULL;
574                 tmp_node->next = head;
575                 head = tmp_node;
576         }
577
578         return PREFERENCE_ERROR_NONE;
579 }
580
581 static int _remove_node(const char *key)
582 {
583         pref_changed_cb_node_t *tmp_node;
584
585         if (key == NULL || key[0] == '\0' )
586         {
587                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
588                 return PREFERENCE_ERROR_INVALID_PARAMETER;
589         }
590
591         tmp_node = _find_node(key);
592
593         if (tmp_node == NULL)
594         {
595                 return PREFERENCE_ERROR_NONE;
596         }
597
598         if (tmp_node->prev != NULL)
599         {
600                 tmp_node->prev->next = tmp_node->next;
601         }
602         else
603         {
604                 head = tmp_node->next;
605         }
606
607         if (tmp_node->next != NULL)
608         {
609                 tmp_node->next->prev = tmp_node->prev;
610         }
611
612         if (tmp_node->key)
613         {
614                 free(tmp_node->key);
615         }
616
617         free(tmp_node);
618
619         return PREFERENCE_ERROR_NONE;
620 }
621
622
623 static void _remove_all_node(void)
624 {
625         pref_changed_cb_node_t *tmp_node;
626
627         while (head)
628         {
629                 tmp_node = head;
630                 head = tmp_node->next;
631
632                 if (tmp_node->key)
633                 {
634                         free(tmp_node->key);
635                 }
636
637                 free(tmp_node);
638         }
639 }
640
641
642 static void _update_cb(void *data, int action, char const *db_name, char const *table_name, sqlite_int64 rowid)
643 {
644         int ret;
645         char *buf;
646         char **result;
647         int rows;
648         int columns;
649         char *errmsg;
650         pref_changed_cb_node_t *tmp_node;
651
652         // skip INSERT/DELETE event
653         if (action != SQLITE_UPDATE)
654         {
655                 return;
656         }
657
658         if (strcmp(table_name, PREF_TBL_NAME) != 0)
659         {
660                 SECURE_LOGE("given table name (%s) is not same", table_name);
661                 return;
662         }
663
664         buf = sqlite3_mprintf("SELECT %s FROM %s WHERE rowid='%lld';", PREF_F_KEY_NAME, PREF_TBL_NAME, rowid);
665         if (buf == NULL)
666         {
667                 return;
668         }
669         ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
670         sqlite3_free(buf);
671         if (ret != SQLITE_OK)
672         {
673                 LOGI("fail to read data(%s)", errmsg);
674                 sqlite3_free(errmsg);
675                 return;
676         }
677
678         if (rows == 0)
679         {
680                 sqlite3_free_table(result);
681                 return;
682         }
683
684         tmp_node = _find_node(result[1]);
685
686         if (tmp_node != NULL && tmp_node->cb != NULL)
687         {
688                 tmp_node->cb(result[1], tmp_node->user_data);
689         }
690
691         sqlite3_free_table(result);
692 }
693
694
695 int preference_remove(const char *key)
696 {
697         int ret;
698         char *buf;
699         bool exist;
700         sqlite3_stmt *stmt;
701
702         ret = preference_is_existing(key, &exist);
703         if (ret != PREFERENCE_ERROR_NONE)
704         {
705                 return ret;
706         }
707
708         if (!exist)
709         {
710                 return PREFERENCE_ERROR_NO_KEY;
711         }
712
713         /* insert data or update data if data already exist */
714         buf = sqlite3_mprintf("DELETE FROM %s WHERE %s = ?",
715                                                         PREF_TBL_NAME, PREF_F_KEY_NAME, key);
716         if (buf == NULL)
717         {
718                 LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
719                 return PREFERENCE_ERROR_IO_ERROR;
720         }
721
722         ret = sqlite3_prepare(pref_db, buf, strlen(buf), &stmt, NULL);
723         if (ret != SQLITE_OK) {
724                 LOGE("IO_ERROR(0x%08x) : fail to prepare query (%d/%s)",
725                         PREFERENCE_ERROR_IO_ERROR,
726                         sqlite3_extended_errcode(pref_db),
727                         sqlite3_errmsg(pref_db));
728                 return PREFERENCE_ERROR_IO_ERROR;
729         }
730
731         ret = sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC);
732         if(ret != SQLITE_OK) {
733                 LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)",
734                         PREFERENCE_ERROR_IO_ERROR,
735                         sqlite3_extended_errcode(pref_db),
736                         sqlite3_errmsg(pref_db));
737                 sqlite3_finalize(stmt);
738                 return PREFERENCE_ERROR_IO_ERROR;
739         }
740
741         ret = sqlite3_step(stmt);
742         if (ret != SQLITE_DONE) {
743                 LOGE("IO_ERROR(0x%08x): fail to delete data(%d/%s)",
744                         PREFERENCE_ERROR_IO_ERROR,
745                         sqlite3_extended_errcode(pref_db),
746                         sqlite3_errmsg(pref_db));
747                 sqlite3_finalize(stmt);
748                 return PREFERENCE_ERROR_IO_ERROR;
749         }
750
751         sqlite3_finalize(stmt);
752         if(buf) {
753                 sqlite3_free(buf);
754                 buf = NULL;
755         }
756
757         // if exist, remove changed cb
758          _remove_node(key);
759
760         return PREFERENCE_ERROR_NONE;
761 }
762
763
764 int preference_remove_all(void)
765 {
766         int ret;
767         char *buf;
768         char *errmsg;
769
770         if (pref_db == NULL)
771         {
772                 if (_initialize() != PREFERENCE_ERROR_NONE)
773                 {
774                         LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
775                         return PREFERENCE_ERROR_IO_ERROR;
776                 }
777         }
778
779         /* insert data or update data if data already exist */
780         buf = sqlite3_mprintf("DELETE FROM %s;", PREF_TBL_NAME);
781         if (buf == NULL)
782         {
783                 LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
784                 return PREFERENCE_ERROR_IO_ERROR;
785         }
786
787         ret = sqlite3_exec(pref_db, buf, NULL, NULL, &errmsg);
788         sqlite3_free(buf);
789         if (ret != SQLITE_OK)
790         {
791                 LOGE("IO_ERROR(0x%08x) : fail to delete data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
792                 sqlite3_free(errmsg);
793                 return PREFERENCE_ERROR_IO_ERROR;
794         }
795
796         // if exist, remove changed cb
797         _remove_all_node();
798
799         return PREFERENCE_ERROR_NONE;
800 }
801
802
803 int preference_set_changed_cb(const char *key, preference_changed_cb callback, void *user_data)
804 {
805         int ret;
806         bool exist;
807
808         ret = preference_is_existing(key, &exist);
809         if (ret != PREFERENCE_ERROR_NONE)
810         {
811                 return ret;
812         }
813
814         if (!exist)
815         {
816                 LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
817                 return PREFERENCE_ERROR_NO_KEY;
818         }
819
820         if (!is_update_hook_registered)
821         {
822                 sqlite3_update_hook(pref_db, _update_cb, NULL);
823                 is_update_hook_registered = true;
824         }
825
826         return _add_node(key, callback, user_data);
827 }
828
829 int preference_unset_changed_cb(const char *key)
830 {
831         int ret;
832         bool exist;
833
834         ret = preference_is_existing(key, &exist);
835         if (ret != PREFERENCE_ERROR_NONE)
836         {
837                 return ret;
838         }
839
840         if (!exist)
841         {
842                 LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
843                 return PREFERENCE_ERROR_NO_KEY;
844         }
845
846         return _remove_node(key);
847 }
848
849 int preference_foreach_item(preference_item_cb callback, void *user_data)
850 {
851         int ret;
852         char *buf;
853         char **result;
854         int rows;
855         int columns;
856         char *errmsg;
857         int i;
858
859         if (callback == NULL)
860         {
861                 LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
862                 return PREFERENCE_ERROR_INVALID_PARAMETER;
863         }
864
865         if (pref_db == NULL)
866         {
867                 if (_initialize() != PREFERENCE_ERROR_NONE)
868                 {
869                         LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
870                         return PREFERENCE_ERROR_IO_ERROR;
871                 }
872         }
873
874         buf = sqlite3_mprintf("SELECT %s FROM %s;", PREF_F_KEY_NAME, PREF_TBL_NAME);
875         if (buf == NULL)
876         {
877                 LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
878                 return PREFERENCE_ERROR_IO_ERROR;
879         }
880
881         ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
882         sqlite3_free(buf);
883         if (ret != SQLITE_OK)
884         {
885                 LOGE("IO_ERROR(0x%08x) : fail to read data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
886                 sqlite3_free(errmsg);
887                 return PREFERENCE_ERROR_IO_ERROR;
888         }
889
890         for (i = 1; i <= rows; i++)
891         {
892                 if (callback(result[i], user_data) != true)
893                 {
894                         break;
895                 }
896         }
897
898         sqlite3_free_table(result);
899
900         return PREFERENCE_ERROR_NONE;
901 }
902