1197 lines
29 KiB
C++
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;
|
|
}
|
|
}
|