Modify flora license version.
[platform/core/messaging/msg-service.git] / utils / MsgSqliteWrapper.cpp
1 /*
2 * Copyright 2012-2013  Samsung Electronics Co., Ltd
3 *
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
7 *
8 *    http://floralicense.org/license/
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 #include <stdio.h>
18 #include <stddef.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include "MsgDebug.h"
24 #include "MsgSqliteWrapper.h"
25
26 extern "C"
27 {
28         #include <db-util.h>
29 }
30
31
32 /*==================================================================================================
33                                      VARIABLES
34 ==================================================================================================*/
35 __thread sqlite3 *handle = NULL;
36 __thread sqlite3_stmt *stmt = NULL;
37 //__thread char **result = NULL;
38
39
40 /*==================================================================================================
41                                      IMPLEMENTATION OF MsgDbHandler - Member Functions
42 ==================================================================================================*/
43 MsgDbHandler::MsgDbHandler()
44 {
45         handle = NULL;
46         stmt = NULL;
47         result = NULL;
48 }
49
50
51 MsgDbHandler::~MsgDbHandler()
52 {
53         if(handle != NULL) {
54                 if (disconnect() != MSG_SUCCESS)
55                         MSG_DEBUG("disconnect is failed!!");
56         }
57
58         if(stmt != NULL)
59                 finalizeQuery();
60
61         if(result != NULL)
62                 freeTable();
63 }
64
65
66 msg_error_t MsgDbHandler::connect()
67 {
68         int ret = 0;
69
70         if (handle == NULL)
71         {
72                 char strDBName[64];
73
74                 memset(strDBName, 0x00, sizeof(strDBName));
75                 snprintf(strDBName, 64, "%s", MSGFW_DB_NAME);
76
77                 ret = db_util_open(strDBName, &handle, DB_UTIL_REGISTER_HOOK_METHOD);
78
79                 if (ret == SQLITE_OK)
80                 {
81                         MSG_DEBUG("DB Connect Success : [%p]", handle);
82                         return MSG_SUCCESS;
83                 }
84                 else
85                 {
86                         MSG_DEBUG("DB Connect Fail [%d]", ret);
87                         return MSG_ERR_DB_CONNECT;
88                 }
89         }
90         else
91         {
92                 MSG_DEBUG("DB Connect exist : [%p]", handle);
93         }
94
95         return MSG_SUCCESS;
96 }
97
98
99 msg_error_t MsgDbHandler::disconnect()
100 {
101         int ret = 0;
102
103         if (handle != NULL)
104         {
105                 ret = db_util_close(handle);
106
107                 if (ret == SQLITE_OK)
108                 {
109                         handle = NULL;
110                         MSG_DEBUG("DB Disconnect Success");
111                         return MSG_SUCCESS;
112                 }
113                 else
114                 {
115                         MSG_DEBUG("DB Disconnect Fail [%d]", ret);
116                         return MSG_ERR_DB_DISCONNECT;
117                 }
118         }
119
120         return MSG_SUCCESS;
121 }
122
123
124 bool MsgDbHandler::checkTableExist(const char *pTableName)
125 {
126         char strQuery[256];
127         int nRowCnt = 0, nResult = 0;
128
129         /* Formulate the Query */
130         memset(strQuery, 0x00, sizeof(strQuery));
131         snprintf(strQuery, sizeof(strQuery), "select count(name) from sqlite_master where name='%s'", pTableName);
132
133         if (getTable(strQuery, &nRowCnt) != MSG_SUCCESS)
134         {
135                 freeTable();
136                 return false;
137         }
138
139         nResult = getColumnToInt(1);
140         MSG_DEBUG("Result [%d]", nResult);
141
142         freeTable();
143
144         if (nResult > 0)
145                 return true;
146         else
147                 return false;
148 }
149
150
151 msg_error_t MsgDbHandler::execQuery(const char *pQuery)
152 {
153         int ret = 0;
154
155         if (!pQuery)
156                 return MSG_ERR_INVALID_PARAMETER;
157
158         if(connect() != MSG_SUCCESS)
159                 return MSG_ERR_DB_DISCONNECT;
160
161         ret = sqlite3_exec(handle, pQuery, 0, 0, NULL);
162
163         if (ret == SQLITE_OK)
164         {
165                 MSG_DEBUG("Execute Query Success");
166                 return MSG_SUCCESS;
167         }
168         else
169         {
170                 MSG_DEBUG("Execute Query Fail [%d]", ret);
171                 return MSG_ERR_DB_EXEC;
172         }
173
174         return MSG_SUCCESS;
175 }
176
177
178 msg_error_t MsgDbHandler::getTable(const char *pQuery, int *pRowCnt)
179 {
180         int ret = 0;
181
182         *pRowCnt = 0;
183
184         if(connect() != MSG_SUCCESS)
185                 return MSG_ERR_DB_DISCONNECT;
186
187         freeTable();
188         ret = sqlite3_get_table(handle, pQuery, &result, pRowCnt, 0, NULL);
189
190         if (ret == SQLITE_OK)
191         {
192                 if (*pRowCnt == 0)    // when the no record return 'MSG_ERR_DB_NORECORD'
193                 {
194                         MSG_DEBUG("No Query Result");
195                         return MSG_ERR_DB_NORECORD;
196                 }
197
198                 MSG_DEBUG("Get Table Success");
199                 return MSG_SUCCESS;
200         }
201         else
202         {
203                 MSG_DEBUG("Get Table Fail [%d]", ret);
204                 return MSG_ERR_DB_GETTABLE;
205         }
206
207         return MSG_SUCCESS;
208 }
209
210
211 void MsgDbHandler::freeTable()
212 {
213         if (result)
214         {
215                 sqlite3_free_table(result);
216                 result = NULL;
217         }
218 }
219
220
221 msg_error_t MsgDbHandler::bindText(const char *pBindStr, int index)
222 {
223         int ret = 0;
224
225         if (pBindStr != NULL)
226                 ret = sqlite3_bind_text(stmt, index, pBindStr, (strlen(pBindStr) + sizeof(unsigned char)), SQLITE_STATIC);
227
228         return ret;
229 }
230
231
232 msg_error_t MsgDbHandler::bindBlob(const void * pBindBlob, int size, int index)
233 {
234         int ret = 0;
235
236         ret = sqlite3_bind_blob(stmt, index, pBindBlob, size, SQLITE_STATIC);
237
238         return ret;
239 }
240
241
242 msg_error_t MsgDbHandler::prepareQuery(const char *pQuery)
243 {
244         int ret = 0;
245
246         stmt = NULL;
247
248         if(connect() != MSG_SUCCESS)
249                 return MSG_ERR_DB_DISCONNECT;
250
251
252         if ((ret = sqlite3_prepare_v2(handle, pQuery, strlen(pQuery), &stmt, NULL)) == SQLITE_OK)
253         {
254                 MSG_DEBUG("Prepare Query Success");
255                 return MSG_SUCCESS;
256         }
257         else
258         {
259                 MSG_DEBUG("Prepare Query Fail [%d]", ret);
260                 return MSG_ERR_DB_PREPARE;
261         }
262
263         return MSG_SUCCESS;
264 }
265
266
267 msg_error_t MsgDbHandler::stepQuery()
268 {
269         int ret = 0;
270
271         ret = sqlite3_step(stmt);
272
273         if (ret == SQLITE_ROW)
274         {
275                 MSG_DEBUG("MsgStepQuery() SQLITE_ROW");
276                 return MSG_ERR_DB_ROW;
277         }
278         else if (ret == SQLITE_DONE)
279         {
280                 MSG_DEBUG("MsgStepQuery() SQLITE_DONE");
281                 return MSG_ERR_DB_DONE;
282         }
283         else
284         {
285                 MSG_DEBUG("MsgStepQuery() Fail [%d]", ret);
286                 return MSG_ERR_DB_STEP;
287         }
288
289         return MSG_SUCCESS;
290 }
291
292
293 void MsgDbHandler::finalizeQuery()
294 {
295         if(stmt != NULL)
296                 sqlite3_finalize(stmt);
297         stmt = NULL;
298 }
299
300
301 int MsgDbHandler::columnInt(int ColumnIndex)
302 {
303         return sqlite3_column_int(stmt, ColumnIndex);
304 }
305
306
307 const unsigned char* MsgDbHandler::columnText(int ColumnIndex)
308 {
309         return sqlite3_column_text(stmt, ColumnIndex);
310 }
311
312
313 const void* MsgDbHandler::columnBlob(int ColumnIndex)
314 {
315         return sqlite3_column_blob(stmt, ColumnIndex);
316 }
317
318
319 msg_error_t MsgDbHandler::beginTrans()
320 {
321         int ret = 0;
322
323         if(connect() != MSG_SUCCESS)
324                 return MSG_ERR_DB_DISCONNECT;
325
326
327         ret = sqlite3_exec(handle, "BEGIN deferred;", 0, 0, NULL);
328
329         if (ret == SQLITE_OK)
330         {
331                 MSG_DEBUG("Begin Transaction Success");
332                 return MSG_SUCCESS;
333         }
334         else
335         {
336                 MSG_DEBUG("Begin Transaction Fail [%d]", ret);
337                 return MSG_ERR_DB_EXEC;
338         }
339
340         return MSG_SUCCESS;
341 }
342
343
344 msg_error_t MsgDbHandler::endTrans(bool Success)
345 {
346         int ret = 0;
347
348         if(connect() != MSG_SUCCESS)
349                 return MSG_ERR_DB_DISCONNECT;
350
351
352         if (Success == true)
353         {
354                 ret = sqlite3_exec(handle, "END;", 0, 0, NULL);
355         }
356         else
357         {
358                 ret = sqlite3_exec(handle, "rollback", 0, 0, NULL);
359                 ret = sqlite3_exec(handle, "END;", 0, 0, NULL);
360         }
361
362         if (ret == SQLITE_OK)
363         {
364                 MSG_DEBUG("End Transaction Success");
365                 return MSG_SUCCESS;
366         }
367         else
368         {
369                 MSG_DEBUG("End Transaction Fail [%d]", ret);
370                 return MSG_ERR_DB_EXEC;
371         }
372
373         return MSG_SUCCESS;
374 }
375
376
377 int MsgDbHandler::getColumnToInt(int RowIndex)
378 {
379         char* pTemp = result[RowIndex];
380
381         int nTemp = 0;
382
383         if (pTemp == NULL)
384         {
385                 MSG_DEBUG("NULL");
386                 return nTemp;
387         }
388
389         nTemp = (int)strtol(pTemp, (char**)NULL, 10);
390
391         return nTemp;
392 }
393
394
395 char MsgDbHandler::getColumnToChar(int RowIndex)
396 {
397         char* pTemp = result[RowIndex];
398
399         if (pTemp == NULL)
400         {
401                 MSG_DEBUG("NULL");
402                 return '\0';
403         }
404
405         return *pTemp;
406 }
407
408
409 void MsgDbHandler::getColumnToString(int RowIndex, int Length, char *pString)
410 {
411         char* pTemp = result[RowIndex];
412
413         if (pTemp == NULL)
414         {
415                 MSG_DEBUG("NULL");
416                 return;
417         }
418
419         strncpy(pString, pTemp, Length);
420 }
421
422
423 msg_error_t MsgDbHandler::getRowId(const char *pTableName, unsigned int *pRowId)
424 {
425         int ret = 0, nRowId = 0, nRowCnt = 0;
426         char strQuery[256];
427
428         if (pTableName == NULL || pRowId == NULL)
429                 return MSG_ERR_INVALID_PARAMETER;
430
431         MSG_DEBUG("Table Name [%s]", pTableName);
432
433         memset(strQuery, 0x00, sizeof(strQuery));
434         snprintf(strQuery, sizeof(strQuery), "select max(rowid) from %s", pTableName);
435
436         ret = getTable(strQuery, &nRowCnt);
437
438         if (ret == SQLITE_OK)
439         {
440                 nRowId = getColumnToInt(1);
441
442                 if ((nRowCnt <= 1) && (nRowId == 0))
443                         *pRowId = 1;
444                 else
445                         *pRowId = nRowId + 1;
446         }
447         else
448         {
449                 MSG_DEBUG("MsgGetRowId failed");
450                 *pRowId = 0;
451                 freeTable();
452                 return MSG_ERR_DB_GETTABLE;
453         }
454
455         freeTable();
456
457         MSG_DEBUG("Row ID [%d]", *pRowId);
458
459         return MSG_SUCCESS;
460 }
461
462
463 /*==================================================================================================
464                                      FUNCTION IMPLEMENTATION
465 ==================================================================================================*/
466 void MsgReleaseMemoryDB()
467 {
468         int freeSize = 0;
469
470         freeSize = sqlite3_release_memory(-1);
471
472         MSG_DEBUG("freed memory size (bytes) : [%d]", freeSize);
473 }
474