2 * Copyright 2012-2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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
8 * http://floralicense.org/license/
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.
27 #include "MsgSqliteWrapper.h"
34 #define MSGFW_DB_INIT_SCRIPT tzplatform_mkpath(TZ_SYS_SHARE,"msg-service/msg_service-init-DB.sh")
36 /*==================================================================================================
38 ==================================================================================================*/
39 __thread sqlite3 *handle = NULL;
40 __thread sqlite3_stmt *stmt = NULL;
41 //__thread char **result = NULL;
44 /*==================================================================================================
45 IMPLEMENTATION OF MsgDbHandler - Member Functions
46 ==================================================================================================*/
47 MsgDbHandler::MsgDbHandler()
53 MsgDbHandler::~MsgDbHandler()
59 msg_error_t MsgDbHandler::connect()
68 memset(strDBName, 0x00, sizeof(strDBName));
69 if (strlen(MSGFW_DB_NAME) >= 64){
70 MSG_DEBUG("DB path is too long");
71 return MSG_ERR_DB_CONNECT;
73 snprintf(strDBName, 64, "%s", MSGFW_DB_NAME);
75 /* Check if the DB exists; if not, create it and initialize it */
76 ret = stat(MSGFW_DB_NAME, &sts);
77 if (ret == -1 && errno == ENOENT){
78 const char *argv_script[] = {"/bin/sh", MSGFW_DB_INIT_SCRIPT, NULL };
79 ret = XSystem(argv_script);
82 ret = db_util_open(strDBName, &handle, DB_UTIL_REGISTER_HOOK_METHOD);
86 MSG_DEBUG("DB Connect Success : [%p]", handle);
91 MSG_DEBUG("DB Connect Fail [%d]", ret);
92 return MSG_ERR_DB_CONNECT;
97 MSG_DEBUG("DB Connect exist : [%p]", handle);
104 msg_error_t MsgDbHandler::disconnect()
110 ret = db_util_close(handle);
112 if (ret == SQLITE_OK)
115 MSG_DEBUG("DB Disconnect Success");
120 MSG_DEBUG("DB Disconnect Fail [%d]", ret);
121 return MSG_ERR_DB_DISCONNECT;
129 bool MsgDbHandler::checkTableExist(const char *pTableName)
132 int nRowCnt = 0, nResult = 0;
134 /* Formulate the Query */
135 memset(strQuery, 0x00, sizeof(strQuery));
136 snprintf(strQuery, sizeof(strQuery), "select count(name) from sqlite_master where name='%s'", pTableName);
138 if (getTable(strQuery, &nRowCnt) != MSG_SUCCESS)
144 nResult = getColumnToInt(1);
145 MSG_DEBUG("Result [%d]", nResult);
156 msg_error_t MsgDbHandler::execQuery(const char *pQuery)
161 return MSG_ERR_INVALID_PARAMETER;
163 if(connect() != MSG_SUCCESS)
164 return MSG_ERR_DB_DISCONNECT;
166 ret = sqlite3_exec(handle, pQuery, 0, 0, NULL);
168 if (ret == SQLITE_OK)
170 MSG_DEBUG("Execute Query Success");
175 MSG_DEBUG("Execute Query Fail [%d]", ret);
176 return MSG_ERR_DB_EXEC;
183 msg_error_t MsgDbHandler::getTable(const char *pQuery, int *pRowCnt)
189 if(connect() != MSG_SUCCESS)
190 return MSG_ERR_DB_DISCONNECT;
193 ret = sqlite3_get_table(handle, pQuery, &result, pRowCnt, 0, NULL);
195 if (ret == SQLITE_OK)
197 if (*pRowCnt == 0) // when the no record return 'MSG_ERR_DB_NORECORD'
199 MSG_DEBUG("No Query Result");
200 return MSG_ERR_DB_NORECORD;
203 MSG_DEBUG("Get Table Success");
208 MSG_DEBUG("Get Table Fail [%d]", ret);
209 return MSG_ERR_DB_GETTABLE;
216 void MsgDbHandler::freeTable()
220 sqlite3_free_table(result);
226 msg_error_t MsgDbHandler::bindText(const char *pBindStr, int index)
230 if (pBindStr != NULL)
231 ret = sqlite3_bind_text(stmt, index, pBindStr, (strlen(pBindStr) + sizeof(unsigned char)), SQLITE_STATIC);
237 msg_error_t MsgDbHandler::bindBlob(const void * pBindBlob, int size, int index)
241 ret = sqlite3_bind_blob(stmt, index, pBindBlob, size, SQLITE_STATIC);
247 msg_error_t MsgDbHandler::prepareQuery(const char *pQuery)
253 if(connect() != MSG_SUCCESS)
254 return MSG_ERR_DB_DISCONNECT;
257 if ((ret = sqlite3_prepare_v2(handle, pQuery, strlen(pQuery), &stmt, NULL)) == SQLITE_OK)
259 MSG_DEBUG("Prepare Query Success");
264 MSG_DEBUG("Prepare Query Fail [%d]", ret);
265 return MSG_ERR_DB_PREPARE;
272 msg_error_t MsgDbHandler::stepQuery()
276 ret = sqlite3_step(stmt);
278 if (ret == SQLITE_ROW)
280 MSG_DEBUG("MsgStepQuery() SQLITE_ROW");
281 return MSG_ERR_DB_ROW;
283 else if (ret == SQLITE_DONE)
285 MSG_DEBUG("MsgStepQuery() SQLITE_DONE");
286 return MSG_ERR_DB_DONE;
290 MSG_DEBUG("MsgStepQuery() Fail [%d]", ret);
291 return MSG_ERR_DB_STEP;
298 void MsgDbHandler::finalizeQuery()
301 sqlite3_finalize(stmt);
306 int MsgDbHandler::columnInt(int ColumnIndex)
308 return sqlite3_column_int(stmt, ColumnIndex);
312 const unsigned char* MsgDbHandler::columnText(int ColumnIndex)
314 return sqlite3_column_text(stmt, ColumnIndex);
318 const void* MsgDbHandler::columnBlob(int ColumnIndex)
320 return sqlite3_column_blob(stmt, ColumnIndex);
324 msg_error_t MsgDbHandler::beginTrans()
328 if(connect() != MSG_SUCCESS)
329 return MSG_ERR_DB_DISCONNECT;
332 ret = sqlite3_exec(handle, "BEGIN deferred;", 0, 0, NULL);
334 if (ret == SQLITE_OK)
336 MSG_DEBUG("Begin Transaction Success");
341 MSG_DEBUG("Begin Transaction Fail [%d]", ret);
342 return MSG_ERR_DB_EXEC;
349 msg_error_t MsgDbHandler::endTrans(bool Success)
353 if(connect() != MSG_SUCCESS)
354 return MSG_ERR_DB_DISCONNECT;
359 ret = sqlite3_exec(handle, "END;", 0, 0, NULL);
363 ret = sqlite3_exec(handle, "rollback", 0, 0, NULL);
364 ret = sqlite3_exec(handle, "END;", 0, 0, NULL);
367 if (ret == SQLITE_OK)
369 MSG_DEBUG("End Transaction Success");
374 MSG_DEBUG("End Transaction Fail [%d]", ret);
375 return MSG_ERR_DB_EXEC;
382 int MsgDbHandler::getColumnToInt(int RowIndex)
384 char* pTemp = result[RowIndex];
394 nTemp = (int)strtol(pTemp, (char**)NULL, 10);
400 char MsgDbHandler::getColumnToChar(int RowIndex)
402 char* pTemp = result[RowIndex];
414 void MsgDbHandler::getColumnToString(int RowIndex, int Length, char *pString)
416 char* pTemp = result[RowIndex];
424 strncpy(pString, pTemp, Length);
428 msg_error_t MsgDbHandler::getRowId(const char *pTableName, unsigned int *pRowId)
430 int ret = 0, nRowId = 0, nRowCnt = 0;
433 if (pTableName == NULL || pRowId == NULL)
434 return MSG_ERR_INVALID_PARAMETER;
436 MSG_DEBUG("Table Name [%s]", pTableName);
438 memset(strQuery, 0x00, sizeof(strQuery));
439 snprintf(strQuery, sizeof(strQuery), "select max(rowid) from %s", pTableName);
441 ret = getTable(strQuery, &nRowCnt);
443 if (ret == SQLITE_OK)
445 nRowId = getColumnToInt(1);
447 if ((nRowCnt <= 1) && (nRowId == 0))
450 *pRowId = nRowId + 1;
454 MSG_DEBUG("MsgGetRowId failed");
457 return MSG_ERR_DB_GETTABLE;
462 MSG_DEBUG("Row ID [%d]", *pRowId);
468 /*==================================================================================================
469 FUNCTION IMPLEMENTATION
470 ==================================================================================================*/
471 void MsgReleaseMemoryDB()
475 freeSize = sqlite3_release_memory(-1);
477 MSG_DEBUG("freed memory size (bytes) : [%d]", freeSize);
481 msg_error_t MsgConvertStrWithEscape(const char *input, char **output)
483 if (input == NULL || output == NULL || strlen(input) == 0) {
484 MSG_DEBUG("MSG_ERR_INVALID_PARAMETER");
485 return MSG_ERR_INVALID_PARAMETER;
492 inputSize = strlen(input);
493 MSG_DEBUG("Size of input string [%d]", inputSize);
495 char tmpStr[(inputSize*2)+3];
496 memset(tmpStr, 0x00, sizeof(tmpStr));
500 for(i=0;i<inputSize;i++) {
501 if (input[i] == '\'' || input[i] == '_' || input[i] == '%' || input[i] == '\\') {
502 tmpStr[j++] = MSGFW_DB_ESCAPE_CHAR;
504 tmpStr[j++] = input[i];
509 *output = strdup(tmpStr);
514 int XSystem(const char *argv[])
521 perror("fork failed");
525 execvp(argv[0], (char *const *)argv);
531 if (waitpid(pid, &status, 0) == -1) {
532 perror("waitpid failed");
535 if (WIFSIGNALED(status)) {
539 if (!WIFEXITED(status)) {
540 /* shouldn't happen */
541 perror("should not happen");
544 return WEXITSTATUS(status);