#include #include #include #include #include #include #include #include #undef LOG_NDEBUG #undef NDEBUG #undef LOG_TAG #define LOG_TAG "DBCtrl" #include using namespace std; using namespace EyeseeLinux; #define RETRY_CNT 3 #define ERR_TIMEOUT -2 #define BEGIN_TRANSACTION "begin transaction" #define COMMIT_TRANSACTION "commit transaction" DBCtrl::DBCtrl() :mName(""), mSQL(""), mColumnCnt(0), mTmpNum(0), mColumnType(NULL), mColumnTypeSize(NULL), mValue(NULL), mColumnName(NULL), mFieldKey(NULL), mDBCon(NULL), mSqlstmt(NULL), mFilter("") { } int DBCtrl::init() { if (access(DB_PATH, F_OK) < 0) { int ret = -1; if ( (ret = mkdir(DB_PATH, 0755)) < 0) { LOGE("mkdir %s failed, %s", DB_PATH, strerror(errno)); return ret; } } mDBCon = DBCon::getInstance(DB_FILE); mSQLCon = mDBCon->getConnect(); return 0; } DBCtrl::~DBCtrl() { if(mDBCon) { LOGD("freeInstance\n"); mDBCon->freeInstance(); mDBCon = NULL; } mSqlstmt = NULL; mSQLCon = NULL; if (mColumnType) { delete [] mColumnType; mColumnType = NULL; } if (mColumnName) { delete [] mColumnName; mColumnName = NULL; } if (mColumnTypeSize) { delete [] mColumnTypeSize; mColumnTypeSize = NULL; } if (mValue) { delete [] mValue; mValue = NULL; } if (mFieldKey) { delete [] mFieldKey; mFieldKey = NULL; } } void DBCtrl::setTableName(const string name) { mName = name; } string DBCtrl::getTableName(void) const { return mName; } void DBCtrl::setSQL(const string sql) { mSQL = sql; } string DBCtrl::getSQL(void) const { return mSQL; } void DBCtrl::setRecord(string columnName, void *pValue) { if(mTmpNum >= mColumnCnt) { LOGE("%s():[%d] invalid mTmpNum: [%d]\n", __FUNCTION__, __LINE__, mTmpNum); return; } mColumnName[mTmpNum] = columnName; mValue[mTmpNum] = (unsigned int)pValue; /* save the column adress */ mTmpNum++; } void DBCtrl::setColumnType(DBC_TYPE *type, int *typeSize) { int i=0; while (i < mColumnCnt) { mColumnType[i] = type[i]; i++; } if (0 != typeSize) { /* just for DB_BLOB */ i = 0; while (i < mColumnCnt) { mColumnTypeSize[mTmpNum] = typeSize[i]; i++; } } } int DBCtrl::insertRecord(void) { int cnt = 0; if (!mSQLCon) { LOGE("mSQLCon is null\n"); return -1; } createAddSQL(); if (mSQL.empty()) { LOGE("mSQL is empty\n"); return -1; } LOGD("SQL is %s\n", mSQL.c_str()); while(mDBCon->lock()) { if (cnt++ > RETRY_CNT) { return ERR_TIMEOUT; } else { usleep(200000); } } int errorCode; errorCode = sqlite3_prepare(mSQLCon, mSQL.c_str(), -1, &mSqlstmt, NULL); if (SQLITE_OK != errorCode) { ERROR(__FUNCTION__, __LINE__, mSQLCon); return errorCode; } int idx = 0; int i; sqlite3_exec(mSQLCon, BEGIN_TRANSACTION, NULL, NULL, NULL); for (i=1; idxunlock(); mTmpNum = 0; /* set to default value */ sqlite3_exec(mSQLCon, COMMIT_TRANSACTION, NULL, NULL, NULL); return errorCode; } sqlite3_finalize(mSqlstmt); mDBCon->unlock(); mTmpNum = 0; /* set to default value */ sqlite3_exec(mSQLCon, COMMIT_TRANSACTION, NULL, NULL, NULL); return SQLITE_OK; } int DBCtrl::bufPrepare(void) { if(mColumnCnt <= 0) return -1; queryBuf = new char[mColumnCnt][100]; return 0; } void DBCtrl::bufRelease(void) { if(queryBuf) { delete []queryBuf; queryBuf = NULL; } } int DBCtrl::prepare(void) { int cnt = 0; if (!mSQLCon) { LOGE("mSQLCon is null\n"); return -1; } createRequerySQL(); if (mSQL.empty()) { LOGE("mSQL is empty\n"); return -1; } while(mDBCon->lock()) { if (cnt++ > RETRY_CNT) { return ERR_TIMEOUT; } else { usleep(200000); } } const char *errorMsg = NULL; int errorCode; LOGD("SQL is %s\n", mSQL.c_str()); errorCode = sqlite3_prepare(mSQLCon, mSQL.c_str(), -1, &mSqlstmt, &errorMsg); if (SQLITE_OK != errorCode) { ERROR(__FUNCTION__, __LINE__, mSQLCon); mDBCon->unlock(); return -1; } if(bufPrepare() == -1) { mDBCon->unlock(); return -1; } mDBCon->unlock(); return 0; } int DBCtrl::finish(void) { int cnt = 0; if (!mSQLCon) { LOGE("mSQLCon is null\n"); return -1; } if (mSQL.empty()) { LOGE("mSQL is empty\n"); return -1; } while(mDBCon->lock()) { if (cnt++ > RETRY_CNT) { return ERR_TIMEOUT; } else { usleep(200000); } } sqlite3_finalize(mSqlstmt); bufRelease(); mDBCon->unlock(); mFilter = ""; return 0; } int DBCtrl::deleteRecord(void) { mSQL = "DELETE FROM "; mSQL.append(mName); mSQL.append(" "); mSQL.append(mFilter); mFilter = ""; return executeSQL(); } int DBCtrl::executeSQL(void) { int cnt = 0; while(mDBCon->lock()) { if (cnt++ > RETRY_CNT) { return ERR_TIMEOUT; } else { usleep(200000); } } char *errorMsg = NULL; int errorCode = sqlite3_exec(mSQLCon, BEGIN_TRANSACTION, NULL, NULL, &errorMsg); if (SQLITE_OK != errorCode) { ERROR(__FUNCTION__, __LINE__, mSQLCon); mDBCon->unlock(); return errorCode; } errorCode = sqlite3_exec(mSQLCon, mSQL.c_str(), NULL, NULL, &errorMsg); if (SQLITE_OK != errorCode) { ERROR(__FUNCTION__, __LINE__, mSQLCon); // return errorCode; } errorCode = sqlite3_exec(mSQLCon, COMMIT_TRANSACTION, NULL, NULL, &errorMsg); if (SQLITE_OK != errorCode) { mDBCon->unlock(); ERROR(__FUNCTION__, __LINE__, mSQLCon); } mDBCon->unlock(); return errorCode; } int DBCtrl::sqlite3Exec(void) { int cnt = 0; while (mDBCon->lock()) { if (cnt++ > RETRY_CNT) { return ERR_TIMEOUT; } else { usleep(200000); } } char *errorMsg = NULL; int errorCode = sqlite3_exec(mSQLCon, mSQL.c_str(), NULL, NULL, &errorMsg); if (SQLITE_OK != errorCode) { ERROR(__FUNCTION__, __LINE__, mSQLCon); return errorCode; } mDBCon->unlock(); return errorCode; } unsigned int DBCtrl::getRecordCnt(void) { if(!mSQLCon) { LOGE("mSQLCon is null\n"); return -1; } string str("SELECT COUNT(*) FROM "); str.append(mName); str.append(" "); str.append(mFilter); setSQL(str); if (mSQL.empty()) { LOGE("mSQL is empty\n"); return -1; } int cnt = 0; while (mDBCon->lock()) { if (cnt++ > RETRY_CNT) { mFilter = ""; return ERR_TIMEOUT; } else { usleep(200000); } } const char *errorMsg = NULL; int errorCode = sqlite3_prepare(mSQLCon, mSQL.c_str(), -1, &mSqlstmt, &errorMsg); if (SQLITE_OK != errorCode) { mDBCon->unlock(); } int recordNum; errorCode = sqlite3_step(mSqlstmt); if (SQLITE_ROW == errorCode) { recordNum = (unsigned int)sqlite3_column_int(mSqlstmt, 0); } else { recordNum = -1; if (SQLITE_DONE != errorCode) { mFilter = ""; ERROR(__FUNCTION__, __LINE__, mSQLCon); } } sqlite3_finalize(mSqlstmt); mDBCon->unlock(); mFilter = ""; return recordNum; } int DBCtrl::getOneLine(void *pValue[]) { const char *errorMsg = NULL; int errorCode; int cnt = 0; while (mDBCon->lock()) { if (cnt++ > RETRY_CNT) { mFilter = ""; return ERR_TIMEOUT; } else { usleep(200000); } } const void *tmpBlob = NULL; int len, i; int idx; const unsigned char *tmpStr; errorCode = sqlite3_step(mSqlstmt); if (SQLITE_ROW == errorCode) { for (idx=0; idx < mColumnCnt; idx++) { switch(mColumnType[idx]) { case DB_UINT32: *(unsigned int *)&pValue[idx] = (unsigned int)sqlite3_column_int(mSqlstmt, idx); break; case DB_INT64: *(long long *)&pValue[idx] = (long long)sqlite3_column_int64(mSqlstmt, idx); break; case DB_UINT16: *(unsigned short *)&pValue[idx] = (unsigned short)sqlite3_column_int(mSqlstmt, idx); pValue[idx] = (void *)&result_uint16; break; case DB_UINT8: *(unsigned char *)&pValue[idx] = (unsigned char)sqlite3_column_int(mSqlstmt, idx); break; case DB_TEXT: tmpStr = sqlite3_column_text(mSqlstmt, idx); if (tmpStr) { memcpy(queryBuf[idx], tmpStr, strlen((const char *)tmpStr) + 1); pValue[idx] = queryBuf[idx]; } else { errorCode = -1; } break; case DB_FLOAT: *(float *)&pValue[idx] = (float)sqlite3_column_double(mSqlstmt, idx); break; case DB_DOUBLE: *(double *)&pValue[idx] = sqlite3_column_double(mSqlstmt, idx); break; #if 0 case DB_BLOB: tmpBlob = sqlite3_column_blob(mSqlstmt, idx); len = sqlite3_column_bytes(mSqlstmt, idx); memcpy((void *)pValue, tmpBlob, len); break; #endif default: break; } } } mDBCon->unlock(); return errorCode; } /* * 查询满足Filter条件的第一条记录 * 返回值: 返回满足Filter条件的记录的数量,返回-1表示查询失败! * */ int DBCtrl::getFilterFirstLine(void *pValue[]) { int errorCode; string str("SELECT * FROM "); str.append(mName); str.append(" "); str.append(mFilter); str.append(" "); str.append("LIMIT 0,1"); setSQL(str); if (mSQL.empty()) { LOGE("mSQL is empty\n"); return -1; } int cnt = 0; while (mDBCon->lock()) { if (cnt++ > RETRY_CNT) { mFilter = ""; return ERR_TIMEOUT; } else { usleep(200000); } } const char *errorMsg = NULL; errorCode = sqlite3_prepare(mSQLCon, mSQL.c_str(), -1, &mSqlstmt, &errorMsg); if (SQLITE_OK != errorCode) { mDBCon->unlock(); } int recordNum; int idx; const void *tmpBlob; char *tmpStr; int len; errorCode = sqlite3_step(mSqlstmt); if (SQLITE_ROW == errorCode) { for (idx=0; idx < mColumnCnt; idx++) { switch(mColumnType[idx]) { case DB_UINT32: *(unsigned int *)&pValue[idx] = (unsigned int)sqlite3_column_int(mSqlstmt, idx); break; case DB_INT64: *(long long *)&pValue[idx] = (long long)sqlite3_column_int64(mSqlstmt, idx); break; case DB_UINT16: *(unsigned short *)&pValue[idx] = (unsigned short)sqlite3_column_int(mSqlstmt, idx); break; case DB_UINT8: *(unsigned char *)&pValue[idx] = (unsigned char)sqlite3_column_int(mSqlstmt, idx); break; case DB_TEXT: tmpStr = (char *)sqlite3_column_text(mSqlstmt, idx); if (tmpStr) { memcpy(queryBuf[idx], tmpStr, strlen(tmpStr) + 1); pValue[idx] = &queryBuf[idx]; } else { errorCode = -1; } break; case DB_FLOAT: *(float *)&pValue[idx] = (float)sqlite3_column_double(mSqlstmt, idx); break; case DB_DOUBLE: *(double *)&pValue[idx] = sqlite3_column_double(mSqlstmt, idx); break; #if 0 case DB_BLOB: tmpBlob = sqlite3_column_blob(mSqlstmt, idx); len = sqlite3_column_bytes(mSqlstmt, idx); memcpy((void *)pValue, tmpBlob, len); break; #endif default: LOGD("not matched type\n"); sqlite3_finalize(mSqlstmt); mDBCon->unlock(); mFilter = ""; return -1; } } } else { ERROR(__FUNCTION__, __LINE__, mSQLCon); sqlite3_finalize(mSqlstmt); mDBCon->unlock(); mFilter = ""; return -1; } sqlite3_finalize(mSqlstmt); mDBCon->unlock(); // mFilter = ""; /* filter will be still used in getRecordCnt */ return getRecordCnt(); } /* * idx: 列在mColumnType中的索引 * 查询满足Filter条件的第一个元素的地址 * 返回值: 返回NULL表示查询失败! * */ void * DBCtrl::getFilterFirstElement(string column, int idx) { int errorCode; void *retAddr = NULL; string str("SELECT "); str.append(column); str.append(" "); str.append("FROM "); str.append(mName); str.append(" "); str.append(mFilter); str.append(" "); str.append("LIMIT 0,1"); setSQL(str); if (mSQL.empty()) { LOGE("mSQL is empty\n"); return NULL; } int cnt = 0; while (mDBCon->lock()) { if (cnt++ > RETRY_CNT) { mFilter = ""; return NULL; } else { usleep(200000); } } const char *errorMsg = NULL; errorCode = sqlite3_prepare(mSQLCon, mSQL.c_str(), -1, &mSqlstmt, &errorMsg); if (SQLITE_OK != errorCode) { mDBCon->unlock(); } int recordNum; const void *tmpBlob; char *tmpStr; int len; errorCode = sqlite3_step(mSqlstmt); if (SQLITE_ROW == errorCode) { switch(mColumnType[idx]) { case DB_UINT32: result_uint32 = (unsigned int)sqlite3_column_int(mSqlstmt, 0); retAddr = (void *)&result_uint32; break; case DB_INT64: result_int64 = (long long)sqlite3_column_int64(mSqlstmt, 0); retAddr = (void *)&result_int64; break; case DB_UINT16: result_uint16 = (unsigned short)sqlite3_column_int(mSqlstmt, 0); retAddr = (void *)&result_uint16; break; case DB_UINT8: result_uint8 = (unsigned char)sqlite3_column_int(mSqlstmt, 0); retAddr = (void *)&result_uint8; break; case DB_TEXT: tmpStr = (char *)sqlite3_column_text(mSqlstmt, 0); if (tmpStr) { memcpy(queryBuf[idx], tmpStr, strlen(tmpStr) + 1); retAddr = &queryBuf[idx]; } else { retAddr = NULL; } break; case DB_FLOAT: result_float = (float)sqlite3_column_double(mSqlstmt, 0); retAddr = (void *)&result_float; break; case DB_DOUBLE: result_double = sqlite3_column_double(mSqlstmt, 0); retAddr = (void *)&result_double; break; #if 0 case DB_BLOB: tmpBlob = sqlite3_column_blob(mSqlstmt, 0); len = sqlite3_column_bytes(mSqlstmt, 0); memcpy((void *)pValue, tmpBlob, len); break; #endif default: retAddr = NULL; break; } } else { ERROR(__FUNCTION__, __LINE__, mSQLCon); } sqlite3_finalize(mSqlstmt); mDBCon->unlock(); mFilter = ""; return retAddr; } /* * Get the specified element, not use filter * Parameter: columnName: the column name int the schema table * columnIdx: the column idx in the sql_tb * rowNumber: row index, start from 0 * */ void * DBCtrl::getElement(string columnName, int columnIdx, unsigned int rowNumber) { int errorCode; void *retAddr = NULL; char buf[20]; bzero(buf, sizeof(buf)); sprintf(buf, "LIMIT %d,1", rowNumber); string str("SELECT "); str.append(columnName); str.append(" "); str.append("FROM "); str.append(mName); str.append(" "); str.append(mFilter); str.append(" "); str.append(buf); setSQL(str); if (mSQL.empty()) { LOGE("mSQL is empty\n"); return NULL; } int cnt = 0; while (mDBCon->lock()) { if (cnt++ > RETRY_CNT) { mFilter = ""; return NULL; } else { usleep(200000); } } const char *errorMsg = NULL; errorCode = sqlite3_prepare(mSQLCon, mSQL.c_str(), -1, &mSqlstmt, &errorMsg); if (SQLITE_OK != errorCode) { mDBCon->unlock(); } int recordNum; const void *tmpBlob; char *tmpStr; int len; errorCode = sqlite3_step(mSqlstmt); if (SQLITE_ROW == errorCode) { switch(mColumnType[columnIdx]) { case DB_UINT32: result_uint32 = (unsigned int)sqlite3_column_int(mSqlstmt, 0); retAddr = (void *)&result_uint32; break; case DB_INT64: result_int64 = (long long)sqlite3_column_int64(mSqlstmt, 0); retAddr = (void *)&result_int64; break; case DB_UINT16: result_uint16 = (unsigned short)sqlite3_column_int(mSqlstmt, 0); retAddr = (void *)&result_uint16; break; case DB_UINT8: result_uint8 = (unsigned char)sqlite3_column_int(mSqlstmt, 0); retAddr = (void *)&result_uint8; break; case DB_TEXT: tmpStr = (char *)sqlite3_column_text(mSqlstmt, 0); if (tmpStr) { memcpy(queryBuf[columnIdx], tmpStr, strlen(tmpStr)); queryBuf[columnIdx][strlen(tmpStr)] = '\0'; retAddr = &queryBuf[columnIdx]; } else { retAddr = NULL; } break; case DB_FLOAT: result_float = (float)sqlite3_column_double(mSqlstmt, 0); retAddr = (void *)&result_float; break; case DB_DOUBLE: result_double = sqlite3_column_double(mSqlstmt, 0); retAddr = (void *)&result_double; break; #if 0 case DB_BLOB: tmpBlob = sqlite3_column_blob(mSqlstmt, 0); len = sqlite3_column_bytes(mSqlstmt, 0); memcpy((void *)pValue, tmpBlob, len); break; #endif default: retAddr = NULL; break; } } else { retAddr = NULL; ERROR(__FUNCTION__, __LINE__, mSQLCon); } sqlite3_finalize(mSqlstmt); mDBCon->unlock(); return retAddr; } void DBCtrl::setColumnCnt(const int num) { mColumnCnt = num; mColumnName = new string[num]; mColumnType = new DBC_TYPE[num]; mColumnTypeSize = new int[num]; mValue = new unsigned int[num]; mFieldKey = new unsigned char[num]; } void DBCtrl::createRequerySQL(void) { int i = 0; string str("SELECT "); mSQL = str; for (i=0; ilock()) { if (cnt++ > RETRY_CNT) { mDBCon->unlock(); return ERR_TIMEOUT; } else { usleep(200000); } } for (i=0; iunlock(); return errorCode; } int DBCtrl::deleteTable(string tbName) { char *errorMsg = NULL; int errorCode; string str("DROP TABLE IF EXISTS "); str += mName; errorCode = sqlite3_exec(mSQLCon, str.c_str(), NULL, NULL, &errorMsg); if(SQLITE_OK != errorCode) { ERROR(__FUNCTION__, __LINE__, mSQLCon); } if (mColumnType) { delete [] mColumnType; mColumnType = NULL; } if (mColumnName) { delete [] mColumnName; mColumnName = NULL; } if (mColumnTypeSize) { delete [] mColumnTypeSize; mColumnTypeSize = NULL; } if (mValue) { delete [] mValue; mValue = NULL; } if (mFieldKey) { delete [] mFieldKey; mFieldKey = NULL; } return errorCode; } void DBCtrl::setFilter(const string filter) { mFilter = filter; }