??? Lingoes界面上的‘語言’字串可以選擇不同的語言,這樣導(dǎo)致其窗口的‘標題’不同,因此對于不同‘語言’界面的Lngoes還需要使用不同的字串傳給FindWndow。這個開始還真沒注意。
??? 另一個問題,當前沒有找到好的HTML Parser,于是打算采用直接分解‘text’的方式獲得結(jié)果。這樣做會使結(jié)果的處理非常的‘受限’,比如如果選擇了多個詞典,text方式處理起來就非常麻煩了。因此當前就先采用‘text’方式,處理一個默認字典先。
??? 今天發(fā)現(xiàn)
wxSQLite3好用,和其封裝MySQL++類似,又能迎合wxWidgets的類型,用起來比較順手。今天的主要動作也是集中在LingosHook本地數(shù)據(jù)庫的設(shè)計和訪問接口的實現(xiàn)上,應(yīng)該說寫好了,就差合并使用了,這個明天再說吧。
??? wxSQLite3相關(guān)代碼如下,記錄一下,下次再用wxSQLite3就有參考了。第一次用,有錯誤再說吧,嘿嘿~

#include?<vector>

#include?"wx/wx.h"

#include?"wx/wxsqlite3.h"

class?CDBAccess


{
public:
????static?const?wxString?TABLENAME_WORD;
????static?const?wxString?TABLENAME_DICTIONARY;
????static?const?wxString?TABLENAME_RESULT;

????static?const?wxString?WORDCLASS_NOUN;
public:

????enum?WordClass?
{?WC_UNKNOWN?=?-1,?WC_NOUN?=?0?};
????typedef?std::pair<int,?wxString>?TResultPair;//wordclass?+?result
????typedef?std::vector<TResultPair>?TResultVector;
????typedef?std::pair<wxString,?TResultVector>?TRecordPair;//dictionary+result?vector
????typedef?std::vector<TRecordPair>?TRecordVector;
????typedef?struct?_RecordData_t

????
{
????????wxString?m_strWord;
????????wxString?m_strSymbol;
????????TRecordVector?m_vctResult;
????????wxString?m_strHTML;
????}?TRecordData;
public:
????CDBAccess();
????virtual?~CDBAccess();

????int?Init(const?wxString&?dbfile);
????
????int?Insert(const?TRecordData&?record);
????int?Remove(const?wxString&?word);
????int?Search(TRecordData&?record);
protected:
????int?InitTables();
????void?Close();

????int?InsertWordTable(const?TRecordData&?record,?wxLongLong&?id);
????int?InsertDictTable(const?wxString&?dict,?wxLongLong&?id);
????int?InsertResultTable(const?wxLongLong&?wordid,?const?wxLongLong&?dictid,?const?TResultPair&?result);

????WordClass?GetWordClass(const?wxString&?type)?const;

????int?RemoveWordTable(const?wxString&?word,?wxLongLong&?id);
????int?RemoveResultTable(const?wxLongLong&?wordid);

????int?SearchWordTable(TRecordData&?record,?wxLongLong&?id);
????int?SearchResultTable(const?wxLongLong&?wordid,?TRecordData&?record);
????const?wxString?SearchDictTable(const?wxLongLong&?dictid);
protected:
????wxString?_strDBFile;

????wxSQLite3Database?_DB;
};
#include?<map>

#include?"wx/wx.h"

#include?"DBAccess.h"


const?wxString?CDBAccess::TABLENAME_WORD????????????=????_("WordTable");
const?wxString?CDBAccess::TABLENAME_DICTIONARY????????=????_("DictionaryTable");
const?wxString?CDBAccess::TABLENAME_RESULT????????????=????_("ResultTable");

const?wxString?CDBAccess::WORDCLASS_NOUN????????????=????_("n.");

CDBAccess::CDBAccess()


{
}

CDBAccess::~CDBAccess()


{
????Close();
}

int?CDBAccess::Init(const?wxString?&dbfile)


{
????try

????
{
????????Close();

????????_DB.Open(dbfile);
????????if(InitTables()?!=?0)
????????????return?-1;
????}
????catch(const?wxSQLite3Exception&?e)

????
{
????????return?-1;
????}
????return?0;
}

int?CDBAccess::InitTables()


{
????try

????
{
????????const?char*?wordtable?=?"CREATE?TABLE?IF?NOT?EXISTS?WordTable?(ID?INTEGER?PRIMARY?KEY?AUTOINCREMENT,Word?VARCHAR(32)?UNIQUE,Symbol?VARCHAR(64),HTML?TEXT,UpdateTime?DATE)";
????????_DB.ExecuteUpdate(wordtable);
????????const?char*?dicttable?=?"CREATE?TABLE?IF?NOT?EXISTS?DictionaryTable?(ID?INTEGER?PRIMARY?KEY?AUTOINCREMENT,Title?VARCHAR(64),UpdateTime?DATE)";
????????_DB.ExecuteUpdate(dicttable);
????????const?char*?resulttable?=?"CREATE?TABLE?IF?NOT?EXISTS?ResultTable?(WordID?INTEGER,DictID?INTEGER,ClassID?INTEGER,Result?VARCHAR(255))";
????????_DB.ExecuteUpdate(resulttable);
????}
????catch(const?wxSQLite3Exception&?e)

????
{
????????return?-1;
????}????

????return?0;
}

void?CDBAccess::Close()


{
????if(_DB.IsOpen())
????????_DB.Close();
}


int?CDBAccess::Insert(const?CDBAccess::TRecordData?&record)


{
????try

????
{
????????_DB.Begin();

????????wxLongLong?wordid?=?0;
????????InsertWordTable(record,?wordid);
????????for(TRecordVector::const_iterator?it?=?record.m_vctResult.begin();?it?!=?record.m_vctResult.end();?++?it)

????????
{
????????????wxLongLong?dictid?=?0;
????????????InsertDictTable(it->first,?dictid);
????????????for(TResultVector::const_iterator?i?=?it->second.begin();?i?!=?it->second.end();?++?i)

????????????
{
????????????????InsertResultTable(wordid,?dictid,?*i);
????????????}
????????}

????????_DB.Commit();
????}
????catch(const?wxSQLite3Exception&?e)

????
{
????????_DB.Rollback();
????????return?-1;
????}
????return?0;
}

int?CDBAccess::InsertWordTable(const?CDBAccess::TRecordData?&record,?wxLongLong?&id)


{
????wxSQLite3Statement?query?=?_DB.PrepareStatement("SELECT?ROWID?FROM?WordTable?WHERE?Word?=??");
????query.Bind(1,?record.m_strWord);
????wxSQLite3ResultSet?res?=?query.ExecuteQuery();
????if(!res.IsOk())
????????throw?wxSQLite3Exception(255,?_("SELECT?ROWID?of?WordTable?FAILED."));
????if(!res.Eof())

????
{
????????id?=?res.GetInt64(0);
????}
????else

????
{
????????wxSQLite3Statement?query?=?_DB.PrepareStatement("INSERT?INTO?WordTable?VALUES(NULL,??,??,??,?DATETIME('NOW',?'LOCALTIME'))");
????????query.Bind(1,?record.m_strWord);
????????query.Bind(2,?record.m_strSymbol);
????????query.Bind(3,?record.m_strHTML);
????????query.ExecuteUpdate();

????????id?=?_DB.GetLastRowId();
????}

????return?0;
}

int?CDBAccess::InsertDictTable(const?wxString&?dict,?wxLongLong?&id)


{
????wxSQLite3Statement?query?=?_DB.PrepareStatement("SELECT?ROWID?FROM?DictionaryTable?WHERE?Title?=??");
????query.Bind(1,?dict);
????wxSQLite3ResultSet?res?=?query.ExecuteQuery();
????if(!res.IsOk())
????????throw?wxSQLite3Exception(255,?_("SELECT?ROWID?of?DictTable?FAILED."));
????if(!res.Eof())

????
{
????????id?=?res.GetInt64(0);
????}
????else

????
{
????????wxSQLite3Statement?query?=?_DB.PrepareStatement("INSERT?INTO?DictionaryTable?VALUES(NULL,??,?DATETIME('NOW',?'LOCALTIME'))");
????????query.Bind(1,?dict);
????????query.ExecuteUpdate();

????????id?=?_DB.GetLastRowId();
????}

????return?0;
}

int?CDBAccess::InsertResultTable(const?wxLongLong?&wordid,?const?wxLongLong?&dictid,?const?TResultPair&?result)


{
//????WordClass?type?=?GetWordClass(result.first);
????
????wxSQLite3Statement?query?=?_DB.PrepareStatement("INSERT?INTO?ResultTable?VALUES(?,??,??,??)");
????query.Bind(1,?wordid);
????query.Bind(2,?dictid);
????query.Bind(3,?result.first);
????query.Bind(4,?result.second);
????query.ExecuteUpdate();????

????return?0;
}

CDBAccess::WordClass?CDBAccess::GetWordClass(const?wxString?&type)?const


{
????if(type?==?WORDCLASS_NOUN)
????????return?WC_NOUN;
????else
????????return?WC_UNKNOWN;
}

int?CDBAccess::Remove(const?wxString?&word)


{
????try

????
{
????????_DB.Begin();
????????
????????wxLongLong?wordid?=?0;
????????RemoveWordTable(word,?wordid);
????????RemoveResultTable(wordid);

????????_DB.Commit();
????}
????catch(const?wxSQLite3Exception&?e)

????
{
????????_DB.Rollback();
????????return?-1;
????}
????return?0;
}

int?CDBAccess::RemoveWordTable(const?wxString?&word,?wxLongLong?&id)


{
????wxSQLite3Statement?query?=?_DB.PrepareStatement("SELECT?ROWID?FROM?WordTable?WHERE?Word?=??");
????query.Bind(1,?word);
????wxSQLite3ResultSet?res?=?query.ExecuteQuery();
????if(!res.IsOk())
????????throw?wxSQLite3Exception(255,?_("SELECT?ROWID?of?WordTable?FAILED."));
????if(!res.Eof())

????
{
????????id?=?res.GetInt64(0);

????????wxSQLite3Statement?query?=?_DB.PrepareStatement("DELETE?FROM?WordTable?WHERE?ID?=??");
????????query.Bind(1,?id);????????
????????query.ExecuteUpdate();
????}
????else

????
{
????????throw?wxSQLite3Exception(254,?_("SELECT?WordTable?FAILED."));
????}

????return?0;
}

int?CDBAccess::RemoveResultTable(const?wxLongLong?&wordid)


{
????wxSQLite3Statement?query?=?_DB.PrepareStatement("DELETE?FROM?ResultTable?WHERE?WordID?=??");
????query.Bind(1,?wordid);????????
????query.ExecuteUpdate();

????return?0;
}

int?CDBAccess::Search(CDBAccess::TRecordData?&record)


{
????try

????
{
????????wxLongLong?wordid?=?0;
????????SearchWordTable(record,?wordid);
????????SearchResultTable(wordid,?record);
????}
????catch(const?wxSQLite3Exception&?e)

????
{
????????return?-1;
????}
????return?0;
}

int?CDBAccess::SearchWordTable(TRecordData&?record,?wxLongLong?&id)


{
????wxSQLite3Statement?query?=?_DB.PrepareStatement("SELECT?ROWID,Symbol?FROM?WordTable?WHERE?Word?=??");
????query.Bind(1,?record.m_strWord);
????wxSQLite3ResultSet?res?=?query.ExecuteQuery();
????if(!res.IsOk())
????????throw?wxSQLite3Exception(255,?_("SELECT?ROWID?of?WordTable?FAILED."));
????if(!res.Eof())

????
{
????????id?=?res.GetInt64(0);
????????record.m_strSymbol?=?res.GetAsString(1);
????}
????else?

????
{
????????throw?wxSQLite3Exception(254,?_("SELECT?WordTable?FAILED."));
????}

????return?0;
}

int?CDBAccess::SearchResultTable(const?wxLongLong&?wordid,?CDBAccess::TRecordData&?record)


{
????wxSQLite3Statement?query?=?_DB.PrepareStatement("SELECT?DictID,?ClassID,?Result?FROM?ResultTable?WHERE?wordid?=??");
????query.Bind(1,?wordid);
????wxSQLite3ResultSet?res?=?query.ExecuteQuery();
????if(!res.IsOk())
????????throw?wxSQLite3Exception(255,?_("SELECT?ROWID?of?ResultTable?FAILED."));
????
????std::map<wxLongLong,?TResultVector>?mapResult;

??????? res.NextRow();//add
????while(!res.Eof())

????
{
????????wxLongLong?dictid?=?res.GetInt64(0);
????????std::map<wxLongLong,?TResultVector>::iterator?it?=?mapResult.find(dictid);
????????if(it?==?mapResult.end())
????????????it?=?mapResult.insert(std::make_pair(dictid,?TResultVector())).first;
????????it->second.push_back(std::make_pair(res.GetInt(1),?res.GetAsString(2)));

????????res.NextRow();
????}

????for(std::map<wxLongLong,?TResultVector>::const_iterator?it?=?mapResult.begin();?it?!=?mapResult.end();?++?it)

????
{
????????wxString?dict?=?SearchDictTable(it->first);
????????record.m_vctResult.push_back(std::make_pair(dict,?it->second));
????}

????return?0;
}

const?wxString?CDBAccess::SearchDictTable(const?wxLongLong?&dictid)


{
????wxSQLite3Statement?query?=?_DB.PrepareStatement("SELECT?Title?FROM?DictionaryTable?WHERE?ID?=??");
????query.Bind(1,?dictid);
????wxSQLite3ResultSet?res?=?query.ExecuteQuery();
????if(!res.IsOk())
????????return?_("FAILED.");
????if(res.Eof())
????????return?_("Unknown.");
????return?res.GetAsString(0);
}