2,新增“Apps”; 3,新增“Common”; 4,新增“FileList”; 5,新增“MediaX”; 6,新增“OpenSource”; 7,新增“Samples”; 8,新增“SoftwareBusinessLines”.
355 lines
7.3 KiB
C++
355 lines
7.3 KiB
C++
#include "GdSQLite3.h"
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
/// \brief GdSQLite3::GdSQLite3
|
||
///
|
||
|
||
GdSQLite3::GdSQLite3()
|
||
{
|
||
m_pDB = nullptr;
|
||
m_bOpen = false;
|
||
|
||
m_strDBName = "";
|
||
m_strLastQueryResult = "";
|
||
}
|
||
|
||
GdSQLite3::~GdSQLite3()
|
||
{
|
||
CloseDB();
|
||
}
|
||
|
||
bool GdSQLite3::OpenDB(const QString& strDBName)
|
||
{
|
||
CloseDB();
|
||
|
||
if(SQLITE_OK != sqlite3_open(strDBName.toStdString().c_str(), &m_pDB) )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
m_strDBName = strDBName;
|
||
|
||
m_bOpen = true;
|
||
|
||
return true;
|
||
}
|
||
|
||
void GdSQLite3::CloseDB()
|
||
{
|
||
if(m_bOpen)
|
||
{
|
||
sqlite3_close(m_pDB);
|
||
m_pDB = nullptr;
|
||
|
||
m_bOpen = false;
|
||
}
|
||
}
|
||
|
||
bool GdSQLite3::IsOpen()
|
||
{
|
||
return m_bOpen;
|
||
}
|
||
|
||
sqlite3* GdSQLite3::GetDB()
|
||
{
|
||
return m_pDB;
|
||
}
|
||
|
||
bool GdSQLite3::Execute(const QString& strSQL)
|
||
{
|
||
if(!m_bOpen)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
char* lpszErrMsg = nullptr;
|
||
|
||
if(SQLITE_OK != sqlite3_exec(m_pDB, strSQL.toStdString().c_str(), &GdSQLite3::CallBack_Execute, nullptr, &lpszErrMsg) )
|
||
{
|
||
sqlite3_free(lpszErrMsg);
|
||
lpszErrMsg = nullptr;
|
||
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// 每查询到1条记录,调用一次
|
||
int GdSQLite3::CallBack_Execute(void* pOwner, int nColCount, char** lpszValue, char** lpszColName)
|
||
{
|
||
GdSQLite3* pThis = reinterpret_cast<GdSQLite3*>(pOwner);
|
||
|
||
if(nullptr == pThis)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
return pThis->DoExecute(nColCount, lpszValue, lpszColName);
|
||
}
|
||
|
||
int GdSQLite3::DoExecute(int nColCount, char** lpszValue, char** lpszColName)
|
||
{
|
||
m_strLastQueryResult = "";
|
||
|
||
for(int i = 0; i < nColCount; i++)
|
||
{
|
||
m_strLastQueryResult += lpszColName[i];
|
||
m_strLastQueryResult += ":";
|
||
m_strLastQueryResult += lpszValue[i] ? lpszValue[i] : "NULL";
|
||
m_strLastQueryResult += "$";
|
||
//printf("%s = %s\n", lpszColName[i], lpszValue[i] ? lpszValue[i] : "NULL");
|
||
}
|
||
//printf("\n");
|
||
|
||
return 0;
|
||
}
|
||
|
||
bool GdSQLite3::QueryAllTableInfo(QString& strResult, const QString& strTable)
|
||
{
|
||
/*
|
||
* sqlite3_get_table
|
||
* 第1个参数不再多说,看前面的例子。
|
||
* 第2个参数是 sql 语句,跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以/0结尾的char *字符串。
|
||
* 第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。
|
||
* 它内存布局是:resultp的字段值是连续的,第一行是字段名称,后面是紧接着是每个字段的值。
|
||
* 从第0索引到第 nColumn - 1索引都是字段名称,从第nColumn 索引开始,后面都是字段值,
|
||
* 它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示。
|
||
* //第n列的名称,存放于resultp [nrow]
|
||
* //第n行第m列的数据,存放于resultp [(nrow+ 1) * nColumn + m]
|
||
* 第4个参数是查询出多少条记录(即查出多少行)。
|
||
* 第5个参数是多少个字段(多少列)。
|
||
* 第6个参数是错误信息。
|
||
*/
|
||
|
||
QString strSQL = "select * from " + strTable;
|
||
|
||
char** lpszResult = nullptr;
|
||
char* lpszErrMsg = nullptr;
|
||
int nRow = 0, nCol = 0;
|
||
|
||
if(!m_bOpen)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if(SQLITE_OK != sqlite3_get_table(m_pDB, strSQL.toStdString().c_str(), &lpszResult, &nRow, &nCol, &lpszErrMsg) )
|
||
{
|
||
sqlite3_free(lpszErrMsg);
|
||
lpszErrMsg = nullptr;
|
||
|
||
return false;
|
||
}
|
||
|
||
//
|
||
strResult = "";
|
||
|
||
int nIndex = nCol; // 第一列为表头
|
||
|
||
for(int i = 0; i < nRow; i++)
|
||
{
|
||
for(int j = 0; j < nCol; j++)
|
||
{
|
||
strResult += lpszResult[j];
|
||
strResult += ":";
|
||
strResult += lpszResult[nIndex];
|
||
if (j < (nCol - 1))
|
||
{
|
||
strResult += ",";
|
||
}
|
||
nIndex++;
|
||
}
|
||
strResult += ";";
|
||
}
|
||
|
||
sqlite3_free_table(lpszResult);
|
||
lpszResult = nullptr;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool GdSQLite3::EgTransaction()
|
||
{
|
||
if(!m_bOpen)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
char* lpszErrMsg = nullptr;
|
||
|
||
/*
|
||
// eg 1
|
||
if(SQLITE_OK != sqlite3_exec(m_pDB, "BEGIN;", nullptr, nullptr, &lpszErrMsg) )
|
||
{
|
||
sqlite3_free(lpszErrMsg);
|
||
lpszErrMsg = nullptr;
|
||
|
||
return false;
|
||
}
|
||
|
||
for(int i = 0; i < 1000; i++)
|
||
{
|
||
QString strSQL = "insert into MyTable(MyText, MyDate, MyTime, MyFloat)"
|
||
" VALUES('--上班好远!', '2022-03-24', '9:00:00', 1000);";
|
||
|
||
if(SQLITE_OK != sqlite3_exec(m_pDB, strSQL.toStdString().c_str(), nullptr, nullptr, &lpszErrMsg) )
|
||
{
|
||
sqlite3_free(lpszErrMsg);
|
||
lpszErrMsg = nullptr;
|
||
}
|
||
}
|
||
|
||
if(SQLITE_OK != sqlite3_exec(m_pDB, "COMMIT;", nullptr, nullptr, &lpszErrMsg) )
|
||
{
|
||
sqlite3_free(lpszErrMsg);
|
||
lpszErrMsg = nullptr;
|
||
|
||
return false;
|
||
}
|
||
|
||
// eg 2
|
||
QString strSQL = "";
|
||
strSQL += "begin;\n";
|
||
|
||
for(int i = 0; i < 1000; i++)
|
||
{
|
||
strSQL += "insert into MyTable values(null, 'test msg');\n";
|
||
}
|
||
|
||
strSQL += "commit;\n";
|
||
|
||
if(SQLITE_OK != sqlite3_exec(m_pDB, strSQL.toStdString().c_str(), nullptr, nullptr, &lpszErrMsg) )
|
||
{
|
||
sqlite3_free(lpszErrMsg);
|
||
lpszErrMsg = nullptr;
|
||
|
||
return false;
|
||
}
|
||
*/
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
/// \brief GdSQLite3RecordSet::GdSQLite3RecordSet
|
||
/// \param pGdSQLite3
|
||
///
|
||
|
||
GdSQLite3RecordSet::GdSQLite3RecordSet(GdSQLite3* pGdSQLite3)
|
||
: m_pGdSQLite3(pGdSQLite3)
|
||
{
|
||
m_pStmt = nullptr;
|
||
|
||
m_bOpen = false;
|
||
m_bValueReady = false;
|
||
}
|
||
|
||
GdSQLite3RecordSet::~GdSQLite3RecordSet()
|
||
{
|
||
Close();
|
||
}
|
||
|
||
bool GdSQLite3RecordSet::Open(const QString& strQuerySQL)
|
||
{
|
||
Close();
|
||
|
||
if(nullptr == m_pGdSQLite3)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if(!m_pGdSQLite3->IsOpen() )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
const char* lpszTail = nullptr;
|
||
|
||
if(SQLITE_OK != sqlite3_prepare_v2(m_pGdSQLite3->GetDB(), strQuerySQL.toStdString().c_str(), -1, &m_pStmt, &lpszTail) )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
m_bOpen = true;
|
||
|
||
return true;
|
||
}
|
||
|
||
void GdSQLite3RecordSet::Close()
|
||
{
|
||
if(m_bOpen)
|
||
{
|
||
if(nullptr != m_pStmt)
|
||
{
|
||
sqlite3_finalize(m_pStmt);
|
||
m_pStmt = nullptr;
|
||
}
|
||
|
||
m_bOpen = false;
|
||
m_bValueReady = false;
|
||
}
|
||
}
|
||
|
||
bool GdSQLite3RecordSet::Next()
|
||
{
|
||
if(!m_bOpen)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
m_bValueReady = false;
|
||
|
||
if(SQLITE_ROW != sqlite3_step(m_pStmt) )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
m_bValueReady = true;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool GdSQLite3RecordSet::GetValue(QVariant& varVal, int nCol, GdSQLite3RecordSet::eDataType eDT)
|
||
{
|
||
if(!m_bValueReady)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
switch(eDT)
|
||
{
|
||
case eDT_Int:
|
||
{
|
||
varVal = sqlite3_column_int(m_pStmt, nCol);
|
||
break;
|
||
}
|
||
case eDT_Int64:
|
||
{
|
||
varVal = sqlite3_column_int64(m_pStmt, nCol);
|
||
break;
|
||
}
|
||
case eDT_Double:
|
||
{
|
||
varVal = sqlite3_column_double(m_pStmt, nCol);
|
||
break;
|
||
}
|
||
case eDT_Text:
|
||
{
|
||
varVal = (char*)sqlite3_column_text(m_pStmt, nCol);
|
||
break;
|
||
}
|
||
case eDT_Blob:
|
||
{
|
||
varVal = QVariant(QByteArray((char*)sqlite3_column_text(m_pStmt, nCol) ) );
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|