Files
envi-code/SourceCode/Code2026/tg_shs/shs_sqlite/UIISQLiteServer.cpp
T
2026-09-28 15:28:50 +08:00

1197 lines
29 KiB
C++

#include "StdAfx.h"
#include "UIISQLiteServer.h"
#include "sqlite3.h"
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <functional>
extern HINSTANCE _hdllInstance;
static std::string g_strErr = "";
namespace
{
CString MiddleString(LPCTSTR psz1, LPCTSTR psz2, LPCTSTR pszSource) // 取出pszSource串中,在 psz1与psz2间的串
{
CString strRel(_T(""));
if (!psz1 || !psz2 || !pszSource) return strRel;
CString sSource(pszSource);
int idx1(-1), idx2(-1);
idx1 = sSource.Find(psz1);
idx2 = sSource.Find(psz2, idx1);
if (idx1 == -1 || idx2 == -1) return strRel;
if (idx1 >= idx2) return strRel;
return sSource.Mid(idx1 + 1, idx2 - idx1 - 1);
}
// 将ansi字符串转换成UNICODE
std::wstring UTF8ToUnicode(LPSTR szText)
{
if (!szText)
return std::wstring(_T(""));
int nLength, nLen;
wchar_t *pBuffer;
nLen = (int)strlen(szText);
nLength = MultiByteToWideChar(CP_UTF8, 0, szText, nLen, NULL, 0);
pBuffer = new wchar_t[nLength + 1];
memset(pBuffer, 0, (nLength+1)*sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, szText, nLen, (LPWSTR)pBuffer, nLength);
std::wstring wstr(pBuffer);
delete[] pBuffer;
return wstr;
}
// 将UNICODE字符串转换成UTF8
std::string UnicodeToUTF8(LPCTSTR szText)
{
char *pBuffer;
int nLength;
int nLen;
nLen = (int)wcslen(szText);
// 获取转换后的字符串长度
nLength = WideCharToMultiByte(CP_UTF8, 0, szText, nLen, NULL, 0, 0, 0);
int rc = GetLastError();
pBuffer = new char[nLength + 1];
memset(pBuffer, 0, (nLength+1)*sizeof(char));
// 进行字符转换
WideCharToMultiByte(CP_UTF8, 0, szText, nLen, pBuffer, nLength, 0, 0);
std::string str(pBuffer);
delete[] pBuffer;
return str;
}
int SplitString(const LPCTSTR pszOri, const LPCTSTR pszSplit, std::vector<CString> &vec)
{
do
{
if (!pszOri) break;
vec.clear();
if (!pszSplit)
{
vec.push_back(pszOri);
return 1;
}
CString sOri(pszOri), sSplit(pszSplit), sRel(_T(""));
int nSplitLen(sSplit.GetLength()), nFindPos(0), nRel(0);
while ((nFindPos = sOri.Find(sSplit, 0)) != -1)
{
sRel = sOri.Mid(0, nFindPos);
vec.push_back(sRel);
sOri = sOri.Right(sOri.GetLength() - nFindPos - nSplitLen);
++nRel;
}
if (!sOri.IsEmpty())
{
vec.push_back(sOri);
++nRel;
}
return nRel;
} while (false);
return 0;
}
CString getMidString(TCHAR chFirst, TCHAR chSecond, LPCTSTR psz)
{
CString str(psz), sRel(_T(""));
int idx = str.Find(chFirst);
if (idx == -1) return _T("");
for (int i = idx+1; i < str.GetLength(); ++i)
{
if (str[i] == chSecond) break;
sRel += str[i];
}
return sRel;
}
}
namespace DBTools
{
struct _Table
{
typedef std::wstring _wstr;
typedef std::vector<_wstr> _wsArr;
public:
struct _Column
{
_wstr __sField;
_wsArr __arData;
_Column() { clear(); }
void clear() { __sField.clear(); __arData.clear(); }
bool empty() { return __sField.empty(); }
bool valid(int row) { return row < __arData.size(); }
};
struct _sort_col_
{
bool operator () (const _Table::_Column &c1, const _Table::_Column &c2) { return c1.__sField < c2.__sField; }
};
struct _find_col_
{
public:
_wstr _field;
_find_col_(const _wstr &f) : _field(f) {}
bool operator () (const _Table::_Column &col) { return col.__sField == _field; }
};
public:
bool empty() { return __table.empty(); }
void clear() { __table.clear(); }
int getNumOfColumn() { return (int)__table.size(); }
int getNumOfRow() { return empty() ? 0 : (int)__table[0].__arData.size(); }
_wstr getData(int row, int col) { return valid(row, col) ? __table[col].__arData[row] : _T(""); }
_wstr getField(int col) { return valid(col) ? __table[col].__sField : _T(""); }
void insert(const _Column & col) { __table.push_back(col); }
const _wsArr* getColumnData(int col) {return valid(col) ? &__table[col].__arData : 0;}
void sort() { std::sort(__table.begin(), __table.end(), _sort_col_()); }
_wstr getData(int row, _wstr sfield)
{
std::vector<_Column>::iterator it = std::find_if(__table.begin(), __table.end(), _find_col_(sfield));
if (it == __table.end()) _wstr();
if (!it->valid(row)) return _wstr();
return it->__arData[row];
}
void getRowData(int row, _wsArr & arr)
{
if (__table.empty()) return;
if (__table[0].__arData.size() <= row) return;
for (size_t i = 0; i < __table.size(); ++i)
arr.push_back(__table[i].__arData[row]);
}
void getData(_wsArr & arr)
{
for (size_t i = 0; i < getNumOfRow(); ++i)
for (size_t j = 0; j < getNumOfColumn(); ++j)
arr.push_back(getData(i, j));
}
private:
bool valid(int col) { return (col < __table.size() && col >= 0); }
bool valid(int row, int col) { return valid(col) ? (row < __table[col].__arData.size() && row >= 0) : false; }
private:
std::vector<_Column> __table;
};
/************************************************************************/
// sqlite3接口查询出的数据二维字符串表。如下图
// 横为行 竖为例 格内为序号,行在前,列在后,通过序号可以读取数据(_Table::getData(row, col))
// | 0 | 1 | 2 | 3 | 4 | 5 | // 列号
// | 0 | 00 | 01 | 02 | 03 | 04 | 05 | // 第一行为字段,以下各行为数据
// | 1 | 10 | 11 | 12 | 13 | 14 | 15 |
// | 2 | 20 | 21 | 22 | 23 | 24 | 25 |
// | 3 | 30 | 31 | 32 | 33 | 34 | 35 |
// | 4 | 40 | 41 | 42 | 43 | 44 | 45 |
// | 5 | 50 | 51 | 52 | 53 | 54 | 55 |
/************************************************************************/
int getSqliteDatas(sqlite3 *db, LPCTSTR zSql, _Table &table)
{
std::string pUTF8 = UnicodeToUTF8(CString(zSql).GetBuffer());
char **pszRel = NULL;
int nRow(0), nCol(0);
int nRel = ::sqlite3_get_table(db, pUTF8.c_str(), &pszRel, &nRow, &nCol, 0);
g_strErr = sqlite3_errmsg(db);
if (nRel == 1 || !pszRel) return nRel;
_Table::_Column col;
std::wstring str(_T(""));
for (int i = 0; i < nCol; ++i)
{
for (int j = 0; j <= nRow; ++j)
{
int n = ((j)*nCol) + i;
str = UTF8ToUnicode(pszRel[n]).c_str();
if (j)
col.__arData.push_back(str);
else
col.__sField = str;
}
table.insert(col);
col.clear();
}
::sqlite3_free_table(pszRel);
return nRel;
}
int sqlite3_get_table(sqlite3 *db, LPCTSTR zSql, char ***pazResult, int *pnRow, int *pnColumn, char **pzErrmsg = 0)
{
CString str(zSql);
std::string pUTF8File = UnicodeToUTF8(str.GetBuffer());
int nRel = ::sqlite3_get_table(db, pUTF8File.c_str(), pazResult, pnRow, pnColumn, pzErrmsg);
if (1 == nRel)
g_strErr = sqlite3_errmsg(db);
return nRel;
}
}
CUIISQLiteServer::CUIISQLiteServer(void)
{
m_pSQLiteDb = NULL;
}
CUIISQLiteServer::~CUIISQLiteServer(void)
{
if (m_pSQLiteDb != NULL)
{
sqlite3_close((sqlite3 *)m_pSQLiteDb);
}
}
BOOL CUIISQLiteServer::InitADOServer(LPCTSTR pszDbFileName)
{
if (m_pSQLiteDb != NULL)
{
sqlite3_close((sqlite3 *)m_pSQLiteDb);
m_pSQLiteDb = NULL;
}
std::string pUTF8File = UnicodeToUTF8((LPWSTR)pszDbFileName);
int nRes = sqlite3_open(pUTF8File.c_str(),(sqlite3 **)&m_pSQLiteDb);
if (nRes != SQLITE_OK)
{
//error can not open database!!!
return FALSE;
}
return TRUE;
}
BOOL CUIISQLiteServer::CreateDBTable(LPCTSTR pszTableName,Ttable& arFields)
{
if (m_pSQLiteDb != NULL)
{
if (IsDbTableExist(pszTableName))
{
return FALSE;
}
CString strSQL,sTemp;
int i;
int nSize = (int)arFields.GetSize();
CUIITableField fieldInfo;
CString keyStr = _T(""),sFormat;
strSQL.Format(_T("CREATE TABLE %s ("),pszTableName);
for( i = 0; i< nSize; i++ )
{
fieldInfo = arFields.GetAt(i);
if( fieldInfo.m_sFieldType == _T("nvarchar") ||
fieldInfo.m_sFieldType == _T("varchar"))
{
sFormat = _T("[%s] %s (%d) ");
if(!fieldInfo.m_bPrimaryKey)
{
if( fieldInfo.m_bIsAllowNull)
{
sFormat += _T("NULL,");
}
else
{
sFormat += _T("NOT NULL,");
}
}
else
{
sFormat += _T("PRIMARY KEY,");
}
sTemp.Format(sFormat, fieldInfo.m_sFieldName,fieldInfo.m_sFieldType, fieldInfo.m_nSize);
}
else if(fieldInfo.m_sFieldType.CompareNoCase(_T("int")) == 0 ||
fieldInfo.m_sFieldType.CompareNoCase(_T("smallint")) == 0)
{
sFormat = _T("[%s] int ");
if(!fieldInfo.m_bPrimaryKey)
{
if( fieldInfo.m_bIsAllowNull)
{
sFormat += _T("NULL,");
}
else
{
sFormat += _T("NOT NULL,");
}
}
else
{
sFormat += _T("PRIMARY KEY,");
}
sTemp.Format(sFormat, fieldInfo.m_sFieldName);
}
else if( fieldInfo.m_sFieldType == _T("float") )
{
sFormat = _T("[%s] float ");
if(!fieldInfo.m_bPrimaryKey)
{
if( fieldInfo.m_bIsAllowNull)
{
sFormat += _T("NULL,");
}
else
{
sFormat += _T("NOT NULL,");
}
}
else
{
sFormat += _T("PRIMARY KEY,");
}
sTemp.Format(sFormat, fieldInfo.m_sFieldName);
}
else if(fieldInfo.m_sFieldType == _T("image"))
{
sFormat = _T("[%s] image NULL,");
sTemp.Format(sFormat, fieldInfo.m_sFieldName);
}
else if(fieldInfo.m_sFieldType == _T("datetime"))
{
sFormat = _T("[%s] datetime DEFAULT GETDATE(),");
sTemp.Format(sFormat, fieldInfo.m_sFieldName);
}
else if(fieldInfo.m_sFieldType == _T("text") ||
fieldInfo.m_sFieldType == _T("ntext"))
{
sFormat = _T("[%s] %s NULL,");
sTemp.Format(sFormat, fieldInfo.m_sFieldName,fieldInfo.m_sFieldType);
}
else if(fieldInfo.m_sFieldType == _T("real"))
{
sFormat = _T("[%s] real ");
if(!fieldInfo.m_bPrimaryKey)
{
if( fieldInfo.m_bIsAllowNull)
{
sFormat += _T("NULL,");
}
else
{
sFormat += _T("NOT NULL,");
}
}
else
{
sFormat += _T("PRIMARY KEY,");
}
sTemp.Format(sFormat, fieldInfo.m_sFieldName);
}
if(sTemp.GetLength() > 0)
{
strSQL += sTemp;
}
sTemp = _T("");
}
int nlen = strSQL.GetLength();
if(nlen > 0)
{
strSQL.SetAt(nlen - 1, _T(')'));
}
else
{
return FALSE;
}
try
{
ExecuteSQL(strSQL);
}
catch(...)
{
return FALSE;
}
return TRUE;
}
return FALSE;
}
BOOL CUIISQLiteServer::IsDbTableExist(LPCTSTR pszTableName)
{
CString sSQL;
sSQL.Format(_T("select count(*) from sqlite_master where type='table' and name='%s'"),pszTableName);
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, sSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
std::wstring str = tbl.getData(0, 0);
int count = _ttoi(str.c_str());
if (count == 0) return FALSE;
return TRUE;
}
static int ParaseString(LPCTSTR pszText,CStringArray& arFields,TCHAR ch = _T(','))
{
CString sTemp,sText;
sText = pszText;
for (int i = 0;i < sText.GetLength();i++)
{
if (sText.GetAt(i) == ch )
{
arFields.Add(sTemp);
sTemp = _T("");
}
else
{
sTemp += sText.GetAt(i);
if (i == sText.GetLength() - 1)
{
arFields.Add(sTemp);
}
}
}
return (int)arFields.GetSize();
}
BOOL CUIISQLiteServer::GetTableStru(LPCTSTR pszTableName,Ttable& arFields,BOOL bTypeAsSQLite)
{
CString sSQL;
sSQL.Format(_T("select * from sqlite_master where type = 'table' and name='%s'"), pszTableName);
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, sSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
// 下面解析字符串
std::wstring wstr = tbl.getData(0, _T("sql"));
CString str(wstr.c_str());
str.Replace(_T("\r\n"), _T("@"));
std::vector<CString> arr(0);
SplitString(str, _T("@"), arr);
CString fname(_T("")), stemp;
Ttable table;
CUIITableField field;
for (size_t i = 0; i < arr.size(); ++i)
{
stemp = arr[i];
stemp.TrimLeft(_T(" "));
fname = stemp;
if (!fname.IsEmpty() && fname[0] != _T('[')) continue;
fname = getMidString(_T('['), _T(']'), fname);
field.m_sFieldName = fname;
field.m_bIsAllowNull = stemp.Find(_T("NOT NULL")) == -1 ? FALSE : TRUE;
field.m_bPrimaryKey = stemp.Find(_T("PRIMARY KEY")) == -1 ? FALSE : TRUE;
// 这里用笨方法即可
if (stemp.Find(_T("CHAR")) != -1)
{
field.m_sFieldType = _T("varchar");
getMidString(_T('('), _T(')'), fname);
field.m_nSize = _ttoi(fname);
}
else if (stemp.Find(_T("INTEGER")) != -1)
field.m_sFieldType = _T("int");
else if (stemp.Find(_T("REAL")) != -1)
field.m_sFieldType = _T("double");
else if (stemp.Find(_T("BLOB")) != -1)
field.m_sFieldType = _T("image");
// else if (stemp.Find(_T("")) != -1)
// field.m_sFieldType = _T("");
// else if (stemp.Find(_T("")) != -1)
// field.m_sFieldType = _T("");
// else if (stemp.Find(_T("")) != -1)
// field.m_sFieldType = _T("");
arFields.Add(field);
}
return TRUE;
}
BOOL CUIISQLiteServer::GetTableStru(LPCTSTR pszTableName,CStringList& listField)
{
CString sSQL;
sSQL.Format(_T("select * from '%s'"), pszTableName);
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, sSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
for (int i = 0; i < tbl.getNumOfColumn(); ++i)
listField.AddTail(tbl.getField(i).c_str());
return TRUE;
}
BOOL CUIISQLiteServer::DeleteTable(LPCTSTR pszTableName)
{
if (m_pSQLiteDb != NULL)
{
CString strSQL;
strSQL.Format(_T("DROP TABLE [%s]"),pszTableName);
ExecuteSQL(strSQL);
return TRUE;
}
return FALSE;
}
BOOL CUIISQLiteServer::DeleteTable(CStringArray& arTableNames)
{
for (int i = 0;i < arTableNames.GetSize();i++)
{
DeleteTable(arTableNames.GetAt(i));
}
return TRUE;
}
BOOL CUIISQLiteServer::AppendTableFields(LPCTSTR pszTableName,Ttable& arFields)
{
if (pszTableName == NULL) return FALSE;
int nSize = (int)arFields.GetSize();
int i,bSuccess = 0;
for(i = 0;i<nSize;i++)
{
bSuccess = AppendTableFields(pszTableName,arFields.GetAt(i));
}
return bSuccess;
}
BOOL CUIISQLiteServer::AppendTableFields(LPCTSTR pszTableName, CUIITableField& arFields)
{
if (pszTableName == NULL) return FALSE;
CString strSQL,sFieldType;
sFieldType = arFields.m_sFieldType;
if( sFieldType.CompareNoCase(_T("varchar")) == 0 ||
sFieldType.CompareNoCase(_T("nvarchar")) == 0)
{
strSQL.Format(_T("ALTER TABLE [%s] ADD [%s] %s(%d)"),pszTableName,arFields.m_sFieldName,
arFields.m_sFieldType,arFields.m_nSize);
}
else
{
strSQL.Format(_T("ALTER TABLE [%s] ADD [%s] %s"),pszTableName,arFields.m_sFieldName,
arFields.m_sFieldType);
}
return ExecuteSQL(strSQL);
}
int CUIISQLiteServer::GetSelData(LPCTSTR pszStrSQL,CString& sValue)
{
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszStrSQL, tbl);
if (nRel == 0 && !tbl.empty())
{
sValue = tbl.getData(0, 0).c_str();
return 1;
}
return 0;
}
int CUIISQLiteServer::GetSelData(LPCTSTR pszStrSQL,CStringArray& arStrValue)
{
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszStrSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
std::vector<std::wstring> vec(0);
tbl.getData(vec);
for (size_t i = 0; i < vec.size(); ++i)
arStrValue.Add(vec[i].c_str());
return arStrValue.GetSize();
}
int CUIISQLiteServer::GetSelData(LPCTSTR pszStrSQL,CStringArray& arStrValue,int nFr, int nTo)
{
if (nTo < nFr || nFr < 0) return FALSE;
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszStrSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
if (tbl.getNumOfRow() <= nFr) return FALSE;
std::vector<std::wstring> vec(0);
tbl.getData(vec);
for (size_t i = nFr; i < vec.size() && i <= nTo; ++i)
arStrValue.Add(vec[i].c_str());
return arStrValue.GetSize();
}
BOOL CUIISQLiteServer::IsSelEmpty(LPCTSTR pszStrSQL)
{
if (m_pSQLiteDb == NULL)
return FALSE;
char** pazResult = NULL;
int nRow = 0,nCol = 0;
DBTools::sqlite3_get_table((sqlite3 *)m_pSQLiteDb, pszStrSQL, &pazResult, &nRow, &nCol, 0);
if (pazResult != NULL && nRow > 1) //第0行为列名
{
sqlite3_free_table(pazResult);
return TRUE;
}
if (pazResult != NULL)
sqlite3_free_table(pazResult);
return FALSE;
}
int CUIISQLiteServer::GetSelData(LPCTSTR pszStrSQL, CStringList& listStrValue, BOOL bMakeLower)
{
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszStrSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
std::vector<std::wstring> vec(0);
tbl.getData(vec);
CString str(_T(""));
for (size_t i = 0; i < vec.size(); ++i)
{
str = vec[i].c_str();
if (bMakeLower) str.MakeLower();
listStrValue.AddTail(str);
}
return listStrValue.GetSize();
}
int CUIISQLiteServer::GetSelData(LPCTSTR pszStrSQL, CStringList& listStrValue, int nFr, int nTo, BOOL bMakeLower)
{
if (nTo < nFr || nFr < 0) return FALSE;
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszStrSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
if (tbl.getNumOfRow() <= nFr) return FALSE;
std::vector<std::wstring> vec(0);
tbl.getData(vec);
listStrValue.RemoveAll();
CString str(_T(""));
for (size_t i = nFr; i < vec.size() && i <= nTo; ++i)
{
str = vec[i].c_str();
if (bMakeLower) str.MakeLower();
listStrValue.AddTail(str);
}
return listStrValue.GetSize();
}
int CUIISQLiteServer::GetSelData(LPCTSTR pszStrSQL,CUIIValueTable& valueTable,BOOL bUpdateLable)
{
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszStrSQL, tbl);
if (nRel == 1 || tbl.empty())
{//如果没有结果,尝试找到表名。
CString tblname(pszStrSQL);
int idx1 = tblname.Find(_T("from"));
tblname = tblname.Mid(idx1);
tblname = getMidString(_T('\''), _T('\''), tblname);// 只找from后面第一个 'xxx'
if (tblname.IsEmpty())
tblname = getMidString(_T('['), _T(']'), tblname);// 只找from后面第一个 'xxx'
CStringList lst;
CStringArray ar;
GetTableStru(tblname, lst);
for (POSITION ps = lst.GetHeadPosition(); ps != NULL;)
ar.Add(lst.GetNext(ps));
valueTable.SetLableRecord(ar);
return valueTable.GetTableLogicSize();
}
CStringArray lable, value;
for (int i=0; i<tbl.getNumOfRow(); i++)
{
std::vector<std::wstring> pStrs(0) ;
tbl.getRowData(i, pStrs);
for (size_t j=0; j<pStrs.size(); ++j)
{
value.Add(pStrs.at(j).c_str()); // 行数据
}
valueTable.AddValueRecord(value);
value.RemoveAll();
}
for (int i = 0; i < tbl.getNumOfColumn(); ++i)
{
lable.Add(tbl.getField(i).c_str());
}
if (bUpdateLable)
valueTable.SetLableRecord(lable);
return valueTable.GetTableLogicSize();
}
int CUIISQLiteServer::GetSelData(LPCTSTR pszStrSQL,CUIIValueTable& valueTable, int nFr, int nTo, BOOL bUpdateLable)
{
if (nTo < nFr || nFr < 0) return FALSE;
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszStrSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
if (tbl.getNumOfRow() <= nFr) return FALSE;
CStringArray lable, value;
for (int i=0; i<tbl.getNumOfRow(); i++)
{
std::vector<std::wstring> pStrs(0) ;
tbl.getRowData(i, pStrs);
for (size_t j=0; j<pStrs.size(); ++j)
{
value.Add(pStrs.at(j).c_str()); // 行数据
}
valueTable.AddValueRecord(value);
value.RemoveAll();
}
for (int i = 0; i < tbl.getNumOfColumn(); ++i)
{
lable.Add(tbl.getField(i).c_str());
}
if (bUpdateLable)
valueTable.SetLableRecord(lable);
return valueTable.GetTableLogicSize();
}
//选取两列,一个为Key,一个为Value建map
int CUIISQLiteServer::GetSelData(LPCTSTR pszSKey_ValueSQL, CMapStringToString& mapKey_Value)
{
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszSKey_ValueSQL, tbl);
if (nRel == 1 || tbl.getNumOfColumn() < 1) return FALSE;
const std::vector<std::wstring> *pCol0 = tbl.getColumnData(0);
const std::vector<std::wstring> *pCol1 = tbl.getColumnData(1);
if (!pCol0 || !pCol1) return FALSE;
for (int i = 0; i < tbl.getNumOfRow(); ++i)
mapKey_Value.SetAt(pCol0->at(i).c_str(), pCol1->at(i).c_str());
return mapKey_Value.GetSize();
}
//选取一行,获得Field到对应数据的映射
int CUIISQLiteServer::GetSelDataEx(LPCTSTR pszSelectSQL,CMapStringToString& mapFieldToValue)
{
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszSelectSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
for (int i = 0; i < tbl.getNumOfColumn(); ++i)
mapFieldToValue.SetAt(tbl.getField(i).c_str(), tbl.getData(0, i).c_str());
return mapFieldToValue.GetSize();
}
int CUIISQLiteServer::GetSelDataEx(LPCTSTR pszSelectSQL, std::map<CString, CString>& mapFieldToValue)
{
if (m_pSQLiteDb == NULL) return FALSE;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, pszSelectSQL, tbl);
if (nRel == 1 || tbl.empty()) return FALSE;
for (int i = 0; i < tbl.getNumOfColumn(); ++i)
mapFieldToValue.insert(std::make_pair(tbl.getField(i).c_str(), tbl.getData(0, i).c_str()));
return mapFieldToValue.size();
}
void CUIISQLiteServer::GetDbTableNameArray(CStringArray& arTables)
{
if (m_pSQLiteDb == NULL) return;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, _T("select name from sqlite_master where type='table'"), tbl);
if (nRel == 1 || tbl.empty()) return;
const std::vector<std::wstring> *pCol = tbl.getColumnData(0);
if (!pCol) return;
for (int i = 0; i < tbl.getNumOfRow(); ++i)
arTables.Add(pCol->at(i).c_str());
}
void CUIISQLiteServer::GetDBTableNameList(CStringList& listTables)
{
if (m_pSQLiteDb == NULL) return;
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pSQLiteDb, _T("select name from sqlite_master where type='table'"), tbl);
if (nRel == 1 || tbl.empty()) return;
const std::vector<std::wstring> *pCol = tbl.getColumnData(0);
if (!pCol) return;
for (int i = 0; i < tbl.getNumOfRow(); ++i)
listTables.AddTail(pCol->at(i).c_str());
}
BOOL CUIISQLiteServer::ExecuteSQL(LPCTSTR pszStrSQL)
{
if (NULL == m_pSQLiteDb || NULL == pszStrSQL)
return FALSE;
std::string pUTF8 = UnicodeToUTF8(CString(pszStrSQL).GetBuffer());
int nRes = sqlite3_exec((sqlite3 *)m_pSQLiteDb,pUTF8.c_str(),NULL,NULL,NULL);
if (nRes != SQLITE_OK)
{
return FALSE;
}
return TRUE;
}
BOOL CUIISQLiteServer::IsDatabaseOpen()
{
return (m_pSQLiteDb != NULL) ? TRUE : FALSE;
}
void CUIISQLiteServer::CloseADOServer()
{
if (m_pSQLiteDb)
{
sqlite3_close((sqlite3 *)m_pSQLiteDb);
m_pSQLiteDb = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
namespace
{
template <class T>
void DeletePtr(T *ptr)
{
if (ptr)
{
delete ptr;
ptr = NULL;
}
}
template <class T>
void DeleteVector(T vec)
{
for (size_t i = 0; i < vec.size(); ++i)
DeletePtr(vec[i]);
vec.clear();
}
}
/*
CREATE TABLE [PBAxis] (
[ID] INT64,
[IsArc] BOOL,
[Name] TEXT,
[StartPointX] DOUBLE,
[StartPointY] DOUBLE,
[StartPointZ] DOUBLE,
[EndPointX] DOUBLE,
[EndPointY] DOUBLE,
[EndPointZ] DOUBLE,
[MiddlePointX] DOUBLE,
[MiddlePointY] DOUBLE,
[MiddlePointZ] DOUBLE)
*/
bool SQLTable::InitFieldInfo(LPCTSTR pszTbl)
{
if (!m_pDb) return false;
if (!pszTbl) return false;
// 初始化字段信息
CString sSQL;
sSQL.Format(_T("select * from sqlite_master where type = 'table' and name='%s'"), pszTbl);
DBTools::_Table tbl;
int nRel = DBTools::getSqliteDatas((sqlite3 *)m_pDb, sSQL, tbl);
if (nRel == 1 || tbl.empty()) return false;
std::wstring wstr = tbl.getData(0, _T("sql"));
CString sSql(wstr.c_str());
// 先取出表名
CString sTblName = MiddleString(_T("["), _T("]"), sSql);
if (sTblName.CompareNoCase(pszTbl) != 0) return false; // 表名与初始化表名不一至
// 取出括号间的内容
CString sBracket = MiddleString(_T("("), _T(")"), sSql);
std::vector<CString> vec(0), vecSub(0);
SplitString(sBracket, _T(","), vec);
CString str(_T(""));
for (size_t i = 0; i < vec.size(); ++i)
{
vecSub.clear();
str = vec[i];
str.TrimLeft();
SplitString(str, _T(" "), vecSub);
if (vecSub.size() != 2) continue;
m_AllOfFields.insert(std::make_pair(MiddleString(_T("["), _T("]"), vecSub[0]), ParserFieldType(vecSub[1])));
}
}
SQLTable::FieldType SQLTable::ParserFieldType(LPCTSTR psz)
{
if (!psz) return eNULL;
CString sType(psz);
if (sType.CompareNoCase(_T("DEC")) == 0 ||
sType.CompareNoCase(_T("DECIMAL")) == 0 ||
sType.CompareNoCase(_T("DOUBLE")) == 0 ||
sType.CompareNoCase(_T("DOUBLE PRECISION")) == 0 ||
sType.CompareNoCase(_T("FLOAT")) == 0 ||
sType.CompareNoCase(_T("REAL")) == 0)
return eFloat;
if (sType.CompareNoCase(_T("INT")) == 0 ||
sType.CompareNoCase(_T("INTEGER")) == 0 ||
sType.CompareNoCase(_T("SMALLINT")) == 0 ||
sType.CompareNoCase(_T("TINYINT")) == 0 ||
sType.CompareNoCase(_T("WORD")) == 0)
return eInt;
if (sType.CompareNoCase(_T("BIGINT")) == 0 ||
sType.CompareNoCase(_T("LARGEINT")) == 0 ||
sType.CompareNoCase(_T("INT64")) == 0 ||
sType.CompareNoCase(_T("AUTOINC")) == 0)
return eLargeint;
if (sType.CompareNoCase(_T("CHAR")) == 0 ||
sType.CompareNoCase(_T("VARCHAR")) == 0 ||
sType.CompareNoCase(_T("VARCHAR2")) == 0 ||
sType.CompareNoCase(_T("TEXT")) == 0 ||
sType.CompareNoCase(_T("DATETEXT")) == 0 ||
sType.CompareNoCase(_T("NCHAR")) == 0 ||
sType.CompareNoCase(_T("NVARCHAR")) == 0 ||
sType.CompareNoCase(_T("NVARCHAR2")) == 0 ||
sType.CompareNoCase(_T("NTEXT")) == 0)
return eWideString;
if (sType.CompareNoCase(_T("CURRENCY")) == 0 ||
sType.CompareNoCase(_T("MONEY")) == 0 ||
sType.CompareNoCase(_T("SMALLMONEY")) == 0)
return eCurrency;
if (sType.CompareNoCase(_T("BLOB")) == 0 ||
sType.CompareNoCase(_T("RAW")) == 0 ||
sType.CompareNoCase(_T("BINARY")) == 0 ||
sType.CompareNoCase(_T("VARBINARY")) == 0)
return eBlob;
if (sType.CompareNoCase(_T("CLOB")) == 0 ||
sType.CompareNoCase(_T("MEMO")) == 0)
return eWideMemo;
if (sType.CompareNoCase(_T("DATETIME")) == 0 ||
sType.CompareNoCase(_T("TIMESTAMP")) == 0)
return eDateTime;
if (sType.CompareNoCase(_T("DATE")) == 0)
return eDate;
if (sType.CompareNoCase(_T("TIME")) == 0)
return eTime;
if (sType.CompareNoCase(_T("BOOLEAN")) == 0 ||
sType.CompareNoCase(_T("BOOL")) == 0)
return eBoolean;
if (sType.CompareNoCase(_T("GRAPHIC")) == 0)
return eGraphic;
return eNULL;
}
bool SQLTable::InitSqlite(LPCTSTR pszDatabase)
{
if (!pszDatabase) return false;
if (m_pDb)
{
sqlite3_close(m_pDb);
m_pDb = NULL;
}
std::string pUTF8File = UnicodeToUTF8((LPWSTR)pszDatabase);
int nRes = sqlite3_open(pUTF8File.c_str(), (sqlite3 **)&m_pDb);
if (nRes != SQLITE_OK)
{
//AfxMessageBox(CString(_T("打开数据库")) + pszDatabase + _T("失败。"));
m_pDb = NULL;
return false;
}
return true;
}
bool SQLTable::QuerySQL(LPCTSTR pszSql, LPCTSTR pszTblName)
{
if (!pszSql || !pszTblName) return false;
if (!m_pDb) return false;
// 清空一切
FreeMemo();
if (!InitFieldInfo(pszTblName)) return false;
std::string pUTF8 = UnicodeToUTF8(CString(pszSql).GetBuffer());
char **pszRel = NULL;
int nRow(0), nCol(0);
int nRel = ::sqlite3_get_table(m_pDb, pUTF8.c_str(), &pszRel, &nRow, &nCol, 0);
g_strErr = sqlite3_errmsg(m_pDb);
if (nRel == 1 || !pszRel) return false;
m_nRows = nRow;
m_nCols = nCol;
// 查询出的数据存在一段连续内存内(pszRel)。总数据量为 (nRow+1)*nCol
// 此段内存由 nRow + 1 段组成。每段分为 nCol 个字符串。
// 第一段保存的是字段信息(共nCol个字段)。其它为具体数据。
// 先取字段
int i = 0;
for (; i < nCol; ++i)
{
SQLCell *pCell = new SQLCell();
pCell->m_iCol = i;
pCell->m_Name = UTF8ToUnicode(pszRel[i]).c_str();
std::map<CString, FieldType>::iterator it = m_AllOfFields.find(pCell->m_Name);
if (it == m_AllOfFields.end()) continue;
pCell->m_type = it->second;
m_QueryOfFields.push_back(pCell);
}
// 再取数据
for (; i < (nRow+1)*nCol; ++i)
{
int idxRow = (int)(i / nCol);
int idxCol = i- (idxRow * nCol);
SQLCell *pCell = new SQLCell(idxRow, idxCol, UTF8ToUnicode(pszRel[i]).c_str(), m_QueryOfFields[idxCol]->m_type, m_QueryOfFields[idxCol]->m_Name);
m_Cells.push_back(pCell);
}
CollectColumns();
CollectRows();
::sqlite3_free_table(pszRel);
return true;
}
SQLTable::~SQLTable()
{
DeleteVector(m_Cells);
DeleteVector(m_QueryOfFields);
ReleaseDB();
}
void SQLTable::CollectColumns()
{
// 按列号排序
std::sort(m_Cells.begin(), m_Cells.end(), SQLCell::CmpByCol());
SQLCellPtrs::const_iterator it1 = m_Cells.begin(), it2 = m_Cells.begin();
SQLCellPtrs vec(0);
for (int i = 0; i < m_nCols; ++i)
{
vec.clear();
std::advance(it1, i*m_nRows);
it2 = it1;
std::advance(it2, m_nRows);
vec.assign(it1, it2);
std::sort(vec.begin(), vec.end(), SQLCell::CmpByRow());
m_Columns.push_back(vec);
it1 = m_Cells.begin();
}
}
void SQLTable::CollectRows()
{
std::sort(m_Cells.begin(), m_Cells.end(), SQLCell::CmpByRow());
SQLCellPtrs::const_iterator it1 = m_Cells.begin(), it2 = m_Cells.begin();
SQLCellPtrs vec(0);
for (int i = 0; i < m_nRows; ++i)
{
vec.clear();
std::advance(it1, i*m_nCols);
it2 = it1;
std::advance(it2, m_nCols);
vec.assign(it1, it2);
std::sort(vec.begin(), vec.end(), SQLCell::CmpByCol());
m_Rows.push_back(vec);
it1 = m_Cells.begin();
}
}
void SQLTable::FreeMemo()
{
DeleteVector(m_Cells);
DeleteVector(m_QueryOfFields);
m_Rows.clear();
m_Columns.clear();
m_AllOfFields.clear();
m_nCols = m_nRows = 0;
}
bool SQLTable::AttachDB(LPCTSTR pszDB)
{
if (!pszDB) return false;
if (m_pDb)
ReleaseDB();
FreeMemo();
return InitSqlite(pszDB);
}
void SQLTable::ReleaseDB()
{
if (m_pDb)
{
sqlite3_close(m_pDb);
m_pDb = NULL;
}
}