#include "StdAfx.h" #include "UIISQLiteServer.h" #include "sqlite3.h" #include #include #include #include #include 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 &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 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 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 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 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 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 pStrs(0) ; tbl.getRowData(i, pStrs); for (size_t j=0; j pStrs(0) ; tbl.getRowData(i, pStrs); for (size_t j=0; j *pCol0 = tbl.getColumnData(0); const std::vector *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& 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 *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 *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 void DeletePtr(T *ptr) { if (ptr) { delete ptr; ptr = NULL; } } template 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 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::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; } }