大佬教程收集整理的这篇文章主要介绍了SQLite3简单C++包装类源码示例,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
const unsigned char *sqlite3_column_text(sqlite3_stmt*,int iCol);
定义是相符合的。
上面是两种完全不同的处理方法。
目前我通过实践,摸透了两个例子
https://github.com/wrmsr/sqliteDB
这个例子我比较欣赏,准备在它的基础上编写一个简单的sqlite C++ wrapper类。参见下面的代码:
// // #ifndef __sqlite3_WRAPPER_H__ #define __sqlite3_WRAPPER_H__ #include <map> #include <String> #include <sstream> #include <vector> #include <memory> #include <stdlib.h> #include <stdio.h> #include <sqlite3.h> class CException: std::exception { public: CException(int _rC): rc(_rC) { Stringstream ss; ss << rc; msg = ss.str(); } CException(const char* _msg): msg(_msg) {} ~CException() throw(){} int getCode() const { return rc; } const char* getmessage() const { return msg.c_str(); } protected: int rc; String msg; }; class Csqlite3; class CQuery{ public: CQuery(Csqlite3& _db,const char* sql); ~CQuery(); Csqlite3& getDB() const { return db; } size_t getPos() const { return pos; } size_t getNumCols() const { return cols.size(); } //最核心的函数,会被反复调用,每次从结果集中读取出一行(IE.一条记录),存放在vals向量中 bool read_one_row(); int getColIDx(const char* col) const; const char* getVal(size_t IDX) const; const char* getVal(const char* col) const; const char* operator[](int idX) const; const char* operator[](const char* col) const; int getVals(map<String,String>& pair) const; private: CQuery(const cquery& src); Csqlite3& db; //database connection object sqlite3_stmt* stmt; //prepared statement object size_t pos; //用于区分出列名而非记录 vector<const char*> cols; //列名组成的向量 vector<const char*> vals; //每次只保存一条记录(也就是一行)的数据,下次处理时会首先清空再存放下一条记录 map<String,int> colIDxs; //列名和索引对应的记录 }; class Csqlite3{ public: Csqlite3(const char* path,int flags = @R_467_5607@OPEN_READWRITE | @R_467_5607@OPEN_CREATE,const char* zVfs = null); ~Csqlite3(); sqlite3* getConn() const { return conn; } typedef int (*CallBACk)(void*,int,char**,char**); voID exec(const char* sql,CallBACk cb = NulL,void* arg = null); String execStr(const char* sql); long long execInt(const char* sql); unsigned long long execUInt(const char* sql); std::auto_ptr<CQuery> execCQuery(const char* sql); int execOne(const char* sql,map<String,String>& pair); private: sqlite3* conn; }; #endif下面是源文件
#include "sqlite3_wrapper.h" CQuery::CQuery(Csqlite3& _db,const char* sql): db(_db),stmt(NulL),pos(0) { int rc = sqlite3_prepare_v2(db.getConn(),sql,-1,&stmt,null); if(rC) throw CException(rc); } CQuery::~CQuery(){ if(stmt) sqlite3_finalize(stmt); } //该函数会反复调用,每次只保存一行的值 bool CQuery::read_one_row() { int rc = sqlite3_step(stmt); if(rc != @R_467_5607@ROW && rc != @R_467_5607@DONE) throw CException(rc); //仅在开始获取列名向量,以后直接跳过 if(pos++ < 1) { size_t numCols = sqlite3_column_count(stmt); cols.reserve(numCols); vals.reserve(numCols); for(size_t i = 0; i < numCols; i++) { const char* col = sqlite3_column_name(stmt,i); cols.push_BACk(col); colIDxs[std::string(col)] = i; } } //如果没有下一条记录就返回,这说明我们已经读完了 if(rc == @R_467_5607@DONE) return false; //还有下一条记录可以读,先清空存放该记录值的向量 vals.clear(); for(size_t i = 0; i < getNumCols(); i++) { const char* val = (const char*)sqlite3_column_text(stmt,i); vals.push_BACk(val); } return true; } //找出列名在向量中对应的索引值 int CQuery::getColIDx(const char* col) const { std::map<std::string,int>::const_iterator i = colIDxs.find(std::string(col)); if(i != colIDxs.end()) return (*i).second; return -1; } const char* CQuery::getVal(size_t IDX) const { if(IDx < 0 || IDx > getNumCols()) return NulL; return vals[IDx]; } const char* CQuery::getVal(const char* col) const { return getVal(getColIDx(col)); } const char* CQuery::operator[](int idX) const { return getVal(IDX); } const char* CQuery::operator[](const char* col) const { return getVal(col); } int CQuery::getVals(map<String,String>& pair) const { for(size_t i = 0; i < getNumCols(); i++) pair[std::string(cols[i])] = getVal(i); return 0; } Csqlite3::Csqlite3(const char* path,int flags,const char* zVfs): conn(NulL) { int rc = sqlite3_open_v2(path,&conn,flags,zVfs); if(rC) throw CException(rc); } Csqlite3::~Csqlite3(){ if(conn) sqlite3_close(conn); } voID Csqlite3::exec(const char* sql,CallBACk cb,void* arg) { char* error = NulL; int rc = sqlite3_exec(conn,cb,arg,&error); if(error) { CException ex(error); sqlite3_free(error); throw ex; } if(rC) throw CException(rc); } String Csqlite3::execStr(const char* sql) { std::string ret; CQuery c(*this,sql); if(c.read_one_row() && c.getNumCols() > 0) ret = c[0]; return ret; } long long Csqlite3::execInt(const char* sql) { CQuery c(*this,sql); if(!c.read_one_row() || c.getNumCols() < 1) return -1; return strtoll(c[0],NulL,10); } unsigned long long Csqlite3::execUInt(const char* sql) { CQuery c(*this,sql); if(!c.read_one_row() || c.getNumCols() < 1) return -1; return strtoull(c[0],10); } std::auto_ptr<CQuery> Csqlite3::execCQuery(const char* sql) { return std::auto_ptr<CQuery>(new CQuery(*this,sql)); } //成功返回0,失败返回1 int Csqlite3::execOne(const char* sql,String>& pair) { CQuery c(*this,sql); if(!c.read_one_row()) { return 1; } return c.getVals(pair); }下面是测试文件
//g++ -g test_sqlite3.cpp sqlite3_wrapper.cpp -o test_sqlite3 -lsqlite3 // #include <iostream> #include <unistd.h> #include "sqlite3_wrapper.h" int main() { try { unlink("test.db"); Csqlite3 db("test.db"); db.exec("create table test(ID int priMary key,value int);"); for(int i = 0; i < 100; i++) { std::stringstream sql; sql << "insert into test values(" << i << "," << i * 2 << ");"; db.exec(sql.str().c_str()); } std::cout << "Max: " << db.execInt("SELEct max(value) from test;") << std::endl; CQuery query(db,"SELEct * FROM test order by value desc;"); while(query.read_one_row()) std::cout << querY["ID"] << " = " << querY["value"] << std::endl; //some arbitrary op to show that you can easily get the sqlite3 object and do whatever to it directly sqlite3_interrupt(db.getConn()); } catch(CException eX) { std::cout << "sqlite exception: " << ex.getmessage() << std::endl; } return 0; }
以上是大佬教程为你收集整理的SQLite3简单C++包装类源码示例全部内容,希望文章能够帮你解决SQLite3简单C++包装类源码示例所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。