[SVACE Issue Fixes]
[platform/core/pim/contacts-service.git] / server / db / ctsvc_db_sqlite.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/time.h>
22 #include <string.h>
23 #include <db-util.h>
24
25 #include "contacts.h"
26 #include "ctsvc_internal.h"
27 #include "ctsvc_db_schema.h"
28 #include "ctsvc_db_sqlite.h"
29 #include "ctsvc_notification.h"
30 #include "ctsvc_number_utils.h"
31
32 #include "ctsvc_db_init.h"
33 #include "ctsvc_db_plugin_person_helper.h"
34 #include "ctsvc_db_plugin_image_helper.h"
35 #include "ctsvc_db_plugin_company_helper.h"
36 #include "ctsvc_db_plugin_group_helper.h"
37
38 #ifdef ENABLE_LOG_FEATURE
39 #include "ctsvc_server_phonelog.h"
40 #endif /* ENABLE_LOG_FEATURE */
41 #include "ctsvc_server_person.h"
42
43 #define CTSVC_QUERY_RETRY_TIME  4
44 #define CTSVC_QUERY_RETRY_INTERVAL      50*1000
45
46 static __thread sqlite3 *ctsvc_db = NULL;
47
48 int ctsvc_db_open(void)
49 {
50         CTS_FN_CALL;
51         int ret;
52
53         if (NULL == ctsvc_db) {
54                 ret = db_util_open(CTSVC_DB_PATH, &ctsvc_db, 0);
55                 if (SQLITE_OK != ret || NULL == ctsvc_db) {
56                         /* LCOV_EXCL_START */
57                         ERR("db_util_open() Fail(%d), ctsvc_db(0x%x)", ret, ctsvc_db);
58                         return CONTACTS_ERROR_DB; /*CTS_ERR_DB_NOT_OPENED*/
59                         /* LCOV_EXCL_STOP */
60                 }
61
62                 ret = sqlite3_create_function(ctsvc_db, "_DATA_DELETE_", 2, SQLITE_UTF8,
63                                 NULL, ctsvc_db_data_delete_callback, NULL, NULL);
64                 if (SQLITE_OK != ret) {
65                         /* LCOV_EXCL_START */
66                         ERR("sqlite3_create_function() Fail(%d)", ret);
67                         return CONTACTS_ERROR_DB;
68                         /* LCOV_EXCL_STOP */
69                 }
70
71                 ret = sqlite3_create_function(ctsvc_db, "_DATA_IMAGE_DELETE_", 1, SQLITE_UTF8,
72                                 NULL, ctsvc_db_image_delete_callback, NULL, NULL);
73                 if (SQLITE_OK != ret) {
74                         /* LCOV_EXCL_START */
75                         ERR("sqlite3_create_function() Fail(%d)", ret);
76                         return CONTACTS_ERROR_DB;
77                         /* LCOV_EXCL_STOP */
78                 }
79
80                 ret = sqlite3_create_function(ctsvc_db, "_DATA_COMPANY_DELETE_", 1, SQLITE_UTF8,
81                                 NULL, ctsvc_db_company_delete_callback, NULL, NULL);
82                 if (SQLITE_OK != ret) {
83                         /* LCOV_EXCL_START */
84                         ERR("sqlite3_create_function() Fail(%d)", ret);
85                         return CONTACTS_ERROR_DB;
86                         /* LCOV_EXCL_STOP */
87                 }
88
89                 ret = sqlite3_create_function(ctsvc_db, "_NORMALIZE_INDEX_", 2, SQLITE_UTF8,
90                                 NULL, ctsvc_db_normalize_str_callback, NULL, NULL);
91                 if (SQLITE_OK != ret) {
92                         /* LCOV_EXCL_START */
93                         ERR("sqlite3_create_function() Fail(%d)", ret);
94                         return CONTACTS_ERROR_DB;
95                         /* LCOV_EXCL_STOP */
96                 }
97 #ifdef ENABLE_LOG_FEATURE
98                 ret = sqlite3_create_function(ctsvc_db, "_PHONE_LOG_DELETE_", 1, SQLITE_UTF8,
99                                 NULL, ctsvc_db_phone_log_delete_callback, NULL, NULL);
100                 if (SQLITE_OK != ret) {
101                         /* LCOV_EXCL_START */
102                         ERR("sqlite3_create_function() Fail(%d)", ret);
103                         return CONTACTS_ERROR_DB;
104                         /* LCOV_EXCL_STOP */
105                 }
106 #endif /* ENABLE_LOG_FEATURE */
107
108                 ret = sqlite3_create_function(ctsvc_db, "_PERSON_DELETE_", 1, SQLITE_UTF8,
109                                 NULL, ctsvc_db_person_delete_callback, NULL, NULL);
110                 if (SQLITE_OK != ret) {
111                         /* LCOV_EXCL_START */
112                         ERR("sqlite3_create_function() Fail(%d)", ret);
113                         return CONTACTS_ERROR_DB;
114                         /* LCOV_EXCL_STOP */
115                 }
116
117                 ret = sqlite3_create_function(ctsvc_db, "_GROUP_DELETE_", 1, SQLITE_UTF8,
118                                 NULL, ctsvc_db_group_delete_callback, NULL, NULL);
119                 if (SQLITE_OK != ret) {
120                         /* LCOV_EXCL_START */
121                         ERR("sqlite3_create_function() Fail(%d)", ret);
122                         return CONTACTS_ERROR_DB;
123                         /* LCOV_EXCL_STOP */
124                 }
125
126                 ret = sqlite3_create_function(ctsvc_db, "_NUMBER_COMPARE_", 4, SQLITE_UTF8,
127                                 NULL, ctsvc_db_phone_number_equal_callback, NULL, NULL);
128                 if (SQLITE_OK != ret) {
129                         /* LCOV_EXCL_START */
130                         ERR("sqlite3_create_function() Fail(%d)", ret);
131                         return CONTACTS_ERROR_DB;
132                         /* LCOV_EXCL_STOP */
133                 }
134
135                 ret = sqlite3_create_collation(ctsvc_db, "_NAME_SORT_", SQLITE_UTF8,
136                                 (void *)SQLITE_UTF8, ctsvc_db_group_name_sort_callback);
137                 if (SQLITE_OK != ret) {
138                         /* LCOV_EXCL_START */
139                         ERR("sqlite3_create_collation() Fail(%d)", ret);
140                         return CONTACTS_ERROR_DB;
141                         /* LCOV_EXCL_STOP */
142                 }
143         }
144
145         return CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
146 }
147
148 int ctsvc_db_close(void)
149 {
150         int ret = 0;
151
152         if (ctsvc_db) {
153                 ret = db_util_close(ctsvc_db);
154                 WARN_IF(SQLITE_OK != ret, "db_util_close() Fail(%d)", ret);
155                 ctsvc_db = NULL;
156                 DBG("The database disconnected really.");
157         }
158
159         return CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
160 }
161
162 int ctsvc_db_change(void)
163 {
164         return sqlite3_changes(ctsvc_db);
165 }
166
167 int ctsvc_db_get_last_insert_id(void)
168 {
169         return sqlite3_last_insert_rowid(ctsvc_db);
170 }
171
172 int ctsvc_db_get_next_id(const char *table)
173 {
174         int id;
175         int ret;
176         char query[CTS_SQL_MAX_LEN] = { 0 };
177
178         snprintf(query, sizeof(query), "SELECT seq FROM %s WHERE name = '%s'",
179                         CTS_SCHEMA_SQLITE_SEQ, table);
180
181         ret = ctsvc_query_get_first_int_result(query, &id);
182         if (ret != CONTACTS_ERROR_NONE) {
183                 if (CONTACTS_ERROR_NO_DATA == ret)
184                         return 1;
185                 else
186                         return id;
187         } else {
188                 return (1 + id);
189         }
190 }
191
192 int ctsvc_query_get_first_int_result(const char *query, int *result)
193 {
194         int ret;
195         struct timeval from, now, diff;
196         bool retry = false;
197         cts_stmt stmt = NULL;
198
199         RETV_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB);
200
201         gettimeofday(&from, NULL);
202         do {
203                 ret = sqlite3_prepare_v2(ctsvc_db, query, strlen(query), &stmt, NULL);
204                 if (ret != SQLITE_OK)
205                         /* LCOV_EXCL_START */
206                         ERR("sqlite3_prepare_v2() Fail(%d, %s)", ret, sqlite3_errmsg(ctsvc_db));
207                 /* LCOV_EXCL_STOP */
208
209                 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
210                         gettimeofday(&now, NULL);
211                         timersub(&now, &from, &diff);
212                         retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME) ? true : false;
213                         if (retry)
214                                 usleep(CTSVC_QUERY_RETRY_INTERVAL);
215                 } else {
216                         retry = false;
217                 }
218         } while (retry);
219
220         if (SQLITE_OK != ret) {
221                 /* LCOV_EXCL_START */
222                 ERR("sqlite3_prepare_v2() Fail(%s)", sqlite3_errmsg(ctsvc_db));
223                 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
224                         return CONTACTS_ERROR_DB_LOCKED;
225                 else
226                         return CONTACTS_ERROR_DB;
227                 /* LCOV_EXCL_STOP */
228         }
229
230         retry = false;
231         gettimeofday(&from, NULL);
232         do {
233                 ret = sqlite3_step(stmt);
234                 if (ret != SQLITE_ROW && SQLITE_DONE != ret) {
235                         /* LCOV_EXCL_START */
236                         ERR("sqlite3_step() Fail(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
237                                         sqlite3_extended_errcode(ctsvc_db));
238                         /* LCOV_EXCL_STOP */
239                 }
240
241                 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
242                         gettimeofday(&now, NULL);
243                         timersub(&now, &from, &diff);
244                         retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME) ? true : false;
245                         if (retry)
246                                 usleep(CTSVC_QUERY_RETRY_INTERVAL);
247                 } else {
248                         retry = false;
249                 }
250         } while (retry);
251
252         if (SQLITE_ROW != ret) {
253                 sqlite3_finalize(stmt);
254                 if (SQLITE_DONE == ret) {
255                         INFO("sqlite3_step() return with SQLITE_DONE (it means NO_DATA) (%d, %s)",
256                                         ret, sqlite3_errmsg(ctsvc_db));
257                         return CONTACTS_ERROR_NO_DATA /*CONTACTS_ERR_DB_RECORD_NOT_FOUND*/;
258                 }
259                 /* LCOV_EXCL_START */
260                 ERR("sqlite3_step() Fail(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
261                                 sqlite3_extended_errcode(ctsvc_db));
262                 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
263                         return CONTACTS_ERROR_DB_LOCKED;
264                 else
265                         return CONTACTS_ERROR_DB;
266                 /* LCOV_EXCL_STOP */
267         }
268
269         *result = sqlite3_column_int(stmt, 0);
270         sqlite3_finalize(stmt);
271
272         return CONTACTS_ERROR_NONE;
273 }
274
275 int ctsvc_query_exec(const char *query)
276 {
277         int ret;
278         cts_stmt stmt = NULL;
279         char *err_msg = NULL;
280
281         RETV_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB);
282
283         ret = ctsvc_query_prepare((char*)query, &stmt);
284         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
285
286         ret = ctsvc_stmt_step(stmt);
287         if (CONTACTS_ERROR_NONE != ret)
288                 /* LCOV_EXCL_START */
289                 ERR("ctsvc_stmt_step() Fail(%d, %s)", ret, err_msg);
290         /* LCOV_EXCL_STOP */
291
292         ctsvc_stmt_finalize(stmt);
293
294         return ret;
295 }
296
297 int ctsvc_query_prepare(char *query, cts_stmt *stmt)
298 {
299         int ret = -1;
300         struct timeval from, now, diff;
301         bool retry = false;
302         *stmt = NULL;
303
304         RETV_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB);
305
306         gettimeofday(&from, NULL);
307         do {
308                 ret = sqlite3_prepare_v2(ctsvc_db, query, strlen(query), stmt, NULL);
309                 if (ret != SQLITE_OK)
310                         /* LCOV_EXCL_START */
311                         ERR("sqlite3_prepare_v2() Fail(%d, %s)", ret, sqlite3_errmsg(ctsvc_db));
312                 /* LCOV_EXCL_STOP */
313
314                 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
315                         gettimeofday(&now, NULL);
316                         timersub(&now, &from, &diff);
317                         retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME) ? true : false;
318                         if (retry)
319                                 usleep(CTSVC_QUERY_RETRY_INTERVAL);
320                 } else {
321                         retry = false;
322                 }
323         } while (retry);
324
325         if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
326                 return CONTACTS_ERROR_DB_LOCKED;
327         else if (ret == SQLITE_OK)
328                 return CONTACTS_ERROR_NONE;
329         else
330                 return CONTACTS_ERROR_DB;
331 }
332
333 int ctsvc_stmt_get_first_int_result(cts_stmt stmt, int *result)
334 {
335         int ret;
336         struct timeval from, now, diff;
337         bool retry = false;
338         RETV_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB);
339
340         gettimeofday(&from, NULL);
341         do {
342                 ret = sqlite3_step(stmt);
343                 if (SQLITE_ROW != ret && SQLITE_DONE != ret)
344                         /* LCOV_EXCL_START */
345                         ERR("sqlite3_step() Fail(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
346                                         sqlite3_extended_errcode(ctsvc_db));
347                 /* LCOV_EXCL_STOP */
348
349                 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
350                         gettimeofday(&now, NULL);
351                         timersub(&now, &from, &diff);
352                         retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME) ? true : false;
353                         if (retry)
354                                 usleep(CTSVC_QUERY_RETRY_INTERVAL);
355                 } else {
356                         retry = false;
357                 }
358         } while (retry);
359
360         if (SQLITE_ROW != ret) {
361                 /* LCOV_EXCL_START */
362                 ERR("sqlite3_step() Fail(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
363                                 sqlite3_extended_errcode(ctsvc_db));
364                 /* LCOV_EXCL_STOP */
365
366                 sqlite3_finalize(stmt);
367                 if (SQLITE_DONE == ret)
368                         return CONTACTS_ERROR_NO_DATA;
369
370                 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
371                         return CONTACTS_ERROR_DB_LOCKED;
372                 else
373                         return CONTACTS_ERROR_DB;
374         }
375
376         *result = sqlite3_column_int(stmt, 0);
377         sqlite3_finalize(stmt);
378
379         return CONTACTS_ERROR_NONE;
380 }
381
382 int ctsvc_stmt_step(cts_stmt stmt)
383 {
384         int ret = CONTACTS_ERROR_NONE;
385         struct timeval from, now, diff;
386         bool retry = false;
387
388         gettimeofday(&from, NULL);
389         do {
390                 ret = sqlite3_step(stmt);
391
392                 if (ret != SQLITE_ROW && ret != SQLITE_DONE) {
393                         /* LCOV_EXCL_START */
394                         ERR("sqlite3_step() Fail(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
395                                         sqlite3_extended_errcode(ctsvc_db));
396                         /* LCOV_EXCL_STOP */
397                 }
398
399                 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
400                         gettimeofday(&now, NULL);
401                         timersub(&now, &from, &diff);
402                         retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME) ? true : false;
403                         if (retry)
404                                 usleep(CTSVC_QUERY_RETRY_INTERVAL);
405                 } else {
406                         retry = false;
407                 }
408         } while (retry);
409
410         switch (ret) {
411         case SQLITE_BUSY:
412         case SQLITE_LOCKED:
413                 ret = CONTACTS_ERROR_DB_LOCKED /*CTS_ERR_DB_LOCK*/;
414                 break;
415         case SQLITE_IOERR:
416                 ret = CONTACTS_ERROR_DB /*CTS_ERR_IO_ERR*/;
417                 break;
418         case SQLITE_FULL:
419                 ret = CONTACTS_ERROR_FILE_NO_SPACE /*CTS_ERR_NO_SPACE*/;
420                 break;
421         case SQLITE_CONSTRAINT:
422                 ret = CONTACTS_ERROR_DB /*CTS_ERR_ALREADY_EXIST*/;
423                 break;
424         case SQLITE_ROW:
425                 ret = 1 /*CTS_TRUE*/;
426                 break;
427         case SQLITE_DONE:
428                 ret = CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
429                 break;
430         case SQLITE_CORRUPT:
431                 ASSERT_NOT_REACHED("the database disk image is malformed");
432                 ret = CONTACTS_ERROR_DB;
433                 break;
434         default:
435                 /* LCOV_EXCL_START */
436                 ERR("sqlite3_step() Fail(%d)", ret);
437                 ret = CONTACTS_ERROR_DB;
438                 /* LCOV_EXCL_STOP */
439         }
440
441         return ret;
442 }
443
444 void ctsvc_stmt_reset(cts_stmt stmt)
445 {
446         sqlite3_reset(stmt);
447         sqlite3_clear_bindings(stmt);
448 }
449
450 void ctsvc_stmt_finalize(cts_stmt stmt)
451 {
452         int ret;
453
454         if (NULL == stmt)
455                 return;
456
457         ret = sqlite3_finalize(stmt);
458         WARN_IF(ret != SQLITE_OK, "sqlite3_finalize Fail(%d, %s, %d)",
459                         ret, sqlite3_errmsg(ctsvc_db), sqlite3_extended_errcode(ctsvc_db));
460 }
461