4 * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <sys/types.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"
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"
38 #ifdef ENABLE_LOG_FEATURE
39 #include "ctsvc_server_phonelog.h"
40 #endif /* ENABLE_LOG_FEATURE */
41 #include "ctsvc_server_person.h"
43 #define CTSVC_QUERY_RETRY_TIME 4
44 #define CTSVC_QUERY_RETRY_INTERVAL 50*1000
46 static __thread sqlite3 *ctsvc_db = NULL;
48 int ctsvc_db_open(void)
53 if (NULL == ctsvc_db) {
54 ret = db_util_open(CTSVC_DB_PATH, &ctsvc_db, 0);
55 if (SQLITE_OK != ret || NULL == ctsvc_db) {
57 ERR("db_util_open() Fail(%d), ctsvc_db(0x%x)", ret, ctsvc_db);
58 return CONTACTS_ERROR_DB; /*CTS_ERR_DB_NOT_OPENED*/
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) {
66 ERR("sqlite3_create_function() Fail(%d)", ret);
67 return CONTACTS_ERROR_DB;
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) {
75 ERR("sqlite3_create_function() Fail(%d)", ret);
76 return CONTACTS_ERROR_DB;
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) {
84 ERR("sqlite3_create_function() Fail(%d)", ret);
85 return CONTACTS_ERROR_DB;
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) {
93 ERR("sqlite3_create_function() Fail(%d)", ret);
94 return CONTACTS_ERROR_DB;
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;
106 #endif /* ENABLE_LOG_FEATURE */
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;
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;
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;
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;
145 return CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
148 int ctsvc_db_close(void)
153 ret = db_util_close(ctsvc_db);
154 WARN_IF(SQLITE_OK != ret, "db_util_close() Fail(%d)", ret);
156 DBG("The database disconnected really.");
159 return CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
162 int ctsvc_db_change(void)
164 return sqlite3_changes(ctsvc_db);
167 int ctsvc_db_get_last_insert_id(void)
169 return sqlite3_last_insert_rowid(ctsvc_db);
172 int ctsvc_db_get_next_id(const char *table)
176 char query[CTS_SQL_MAX_LEN] = { 0 };
178 snprintf(query, sizeof(query), "SELECT seq FROM %s WHERE name = '%s'",
179 CTS_SCHEMA_SQLITE_SEQ, table);
181 ret = ctsvc_query_get_first_int_result(query, &id);
182 if (ret != CONTACTS_ERROR_NONE) {
183 if (CONTACTS_ERROR_NO_DATA == ret)
192 int ctsvc_query_get_first_int_result(const char *query, int *result)
195 struct timeval from, now, diff;
197 cts_stmt stmt = NULL;
199 RETV_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB);
201 gettimeofday(&from, NULL);
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));
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;
214 usleep(CTSVC_QUERY_RETRY_INTERVAL);
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;
226 return CONTACTS_ERROR_DB;
231 gettimeofday(&from, NULL);
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));
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;
246 usleep(CTSVC_QUERY_RETRY_INTERVAL);
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*/;
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;
265 return CONTACTS_ERROR_DB;
269 *result = sqlite3_column_int(stmt, 0);
270 sqlite3_finalize(stmt);
272 return CONTACTS_ERROR_NONE;
275 int ctsvc_query_exec(const char *query)
278 cts_stmt stmt = NULL;
279 char *err_msg = NULL;
281 RETV_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB);
283 ret = ctsvc_query_prepare((char*)query, &stmt);
284 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
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);
292 ctsvc_stmt_finalize(stmt);
297 int ctsvc_query_prepare(char *query, cts_stmt *stmt)
300 struct timeval from, now, diff;
304 RETV_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB);
306 gettimeofday(&from, NULL);
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));
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;
319 usleep(CTSVC_QUERY_RETRY_INTERVAL);
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;
330 return CONTACTS_ERROR_DB;
333 int ctsvc_stmt_get_first_int_result(cts_stmt stmt, int *result)
336 struct timeval from, now, diff;
338 RETV_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB);
340 gettimeofday(&from, NULL);
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));
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;
354 usleep(CTSVC_QUERY_RETRY_INTERVAL);
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));
366 sqlite3_finalize(stmt);
367 if (SQLITE_DONE == ret)
368 return CONTACTS_ERROR_NO_DATA;
370 if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
371 return CONTACTS_ERROR_DB_LOCKED;
373 return CONTACTS_ERROR_DB;
376 *result = sqlite3_column_int(stmt, 0);
377 sqlite3_finalize(stmt);
379 return CONTACTS_ERROR_NONE;
382 int ctsvc_stmt_step(cts_stmt stmt)
384 int ret = CONTACTS_ERROR_NONE;
385 struct timeval from, now, diff;
388 gettimeofday(&from, NULL);
390 ret = sqlite3_step(stmt);
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));
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;
404 usleep(CTSVC_QUERY_RETRY_INTERVAL);
413 ret = CONTACTS_ERROR_DB_LOCKED /*CTS_ERR_DB_LOCK*/;
416 ret = CONTACTS_ERROR_DB /*CTS_ERR_IO_ERR*/;
419 ret = CONTACTS_ERROR_FILE_NO_SPACE /*CTS_ERR_NO_SPACE*/;
421 case SQLITE_CONSTRAINT:
422 ret = CONTACTS_ERROR_DB /*CTS_ERR_ALREADY_EXIST*/;
425 ret = 1 /*CTS_TRUE*/;
428 ret = CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
431 ASSERT_NOT_REACHED("the database disk image is malformed");
432 ret = CONTACTS_ERROR_DB;
435 /* LCOV_EXCL_START */
436 ERR("sqlite3_step() Fail(%d)", ret);
437 ret = CONTACTS_ERROR_DB;
444 void ctsvc_stmt_reset(cts_stmt stmt)
447 sqlite3_clear_bindings(stmt);
450 void ctsvc_stmt_finalize(cts_stmt stmt)
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));