Codejie's C++ Space

Using C++

LingosHook:wxSQLite3不错


    Lingoes界面上的‘语言’字串可以选择不同的语言,这样导致其窗口的‘标题’不同,因此对于不同‘语言’界面的Lngoes还需要使用不同的字串传给FindWndow。这个开始还真没注意。
    另一个问题,当前没有找到好的HTML Parser,于是打算采用直接分解‘text’的方式获得结果。这样做会使结果的处理非常的‘受限’,比如如果选择了多个词典,text方式处理起来就非常麻烦了。因此当前就先采用‘text’方式,处理一个默认字典先。
    今天发现wxSQLite3好用,和其封装MySQL++类似,又能迎合wxWidgets的类型,用起来比较顺手。今天的主要动作也是集中在LingosHook本地数据库的设计和访问接口的实现上,应该说写好了,就差合并使用了,这个明天再说吧。

    wxSQLite3相关代码如下,记录一下,下次再用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);
}


posted on 2009-11-17 18:57 codejie 阅读(1200) 评论(4)  编辑 收藏 引用 所属分类: C++

评论

# re: LingosHook:wxSQLite3不错[未登录] 2009-11-18 02:08 Liu

损你归损你,不过我得承认业余时间看看你的blog也是享受,又放松又学习了。

现在你也不上MSN了,好像也就这里能和你聊聊天了  回复  更多评论   

# re: LingosHook:wxSQLite3不错 2009-11-18 10:07 codejie

@Liu
我也想MSN啊,但现在的环境不像咱们以前啊,这里我就发现不了代理啊。上班对着电脑,一句话不说对我也是折磨啊,好怀念那时一起‘飞扬跋扈’的上班时光。。。
不过咱们MSN聊什么呢?技术?上班够无聊的了;MM?年纪都一大把了;小孩?咱们男女不同,用的尿片都不一样啊。。。你说,咱们除了互相诋毁之外,似乎也没别的要说了,嘿嘿。。。

另:
我打算收你的阅读费,不过分吧。。。。  回复  更多评论   

# re: LingosHook:wxSQLite3不错[未登录] 2009-11-18 14:55 Liu

@codejie

你真是典型的给脸不要脸啊……  回复  更多评论   

# re: LingosHook:wxSQLite3不错 2009-11-18 16:30 codejie

@Liu
哇哈哈。。。。

你Y是没睡呢,还是早起呢,还是在给宝宝泡奶呢?这时间好怪啊~咱们时差到底多少啊~别说你Y又跑到火星去了~  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

Using C++

导航

统计

留言簿(73)

随笔分类(513)

积分与排名

最新评论

阅读排行榜

评论排行榜