Commit b6f3f03f authored by Pavel Vainerman's avatar Pavel Vainerman

(SQLiteInterface): переделал интерфейс. Ввёл клас SQLiteResult, чтобы с ним…

(SQLiteInterface): переделал интерфейс. Ввёл клас SQLiteResult, чтобы с ним работать как с stl-контейнерами.
parent 5d08e644
......@@ -108,6 +108,7 @@ void DBServer_SQLite::sysCommand( UniSetTypes::SystemMessage *sm )
case SystemMessage::Finish:
{
activate = false;
// db->freeResult();
db->close();
}
break;
......@@ -115,6 +116,7 @@ void DBServer_SQLite::sysCommand( UniSetTypes::SystemMessage *sm )
case SystemMessage::FoldUp:
{
activate = false;
// db->freeResult();
db->close();
}
break;
......@@ -179,6 +181,7 @@ void DBServer_SQLite::parse( UniSetTypes::ConfirmMessage* cem )
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << myname << "(update_confirm): db error: "<< db->error() << endl;
// db->freeResult();
}
}
catch( Exception& ex )
......@@ -231,7 +234,10 @@ bool DBServer_SQLite::writeToBase( const string& query )
// см. SQLiteInterface::query.
string err(db->error());
if( err.empty() )
{
// db->freeResult();
return true;
}
return false;
}
......@@ -243,6 +249,7 @@ void DBServer_SQLite::flushBuffer()
// Сперва пробуем очистить всё что накопилось в очереди до этого...
while( !qbuf.empty() )
{
#if 0
db->query( qbuf.front() );
// Дело в том что на INSERT И UPDATE запросы
......@@ -250,13 +257,14 @@ void DBServer_SQLite::flushBuffer()
// отдельно проверять действительно ли произошла ошибка
// см. SQLiteInterface::query.
string err(db->error());
if( err.empty() && unideb.debugging(Debug::CRIT) )
if( err.empty() )
db->freeResult();
else if( unideb.debugging(Debug::CRIT) )
{
unideb[Debug::CRIT] << myname << "(writeToBase): error: " << err <<
" lost query: " << qbuf.front() << endl;
}
#endif
qbuf.pop();
}
}
......@@ -291,6 +299,7 @@ void DBServer_SQLite::parse( UniSetTypes::SensorMessage *si )
{
if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << myname << "(insert) sensor msg error: "<< db->error() << endl;
// db->freeResult();
}
}
catch( Exception& ex )
......
......@@ -32,7 +32,6 @@ using namespace UniSetTypes;
SQLiteInterface::SQLiteInterface():
db(0),
curStmt(0),
lastQ(""),
queryok(false),
connected(false),
......@@ -53,7 +52,7 @@ bool SQLiteInterface::connect( const string dbfile )
{
int rc = sqlite3_open(dbfile.c_str(), &db);
if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED || rc==SQLITE_INTERRUPT || rc==SQLITE_IOERR )
if( rc != SQLITE_OK )
{
cerr << "SQLiteInterface::connect): rc=" << rc << " error: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db);
......@@ -86,17 +85,19 @@ bool SQLiteInterface::insert( const string q )
sqlite3_stmt* pStmt;
// Компилируем SQL запрос
sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL);
if( sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL) != SQLITE_OK )
{
queryok=false;
return false;
}
int rc = sqlite3_step(pStmt);
if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED || rc==SQLITE_INTERRUPT || rc==SQLITE_IOERR )
if( !checkResult(rc) && !wait(pStmt, SQLITE_DONE) )
{
if( !wait(pStmt, SQLITE_DONE) )
{
sqlite3_finalize(pStmt);
queryok=false;
return false;
}
sqlite3_finalize(pStmt);
queryok=false;
return false;
}
sqlite3_finalize(pStmt);
......@@ -104,45 +105,35 @@ bool SQLiteInterface::insert( const string q )
return true;
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::query( const string q )
bool SQLiteInterface::checkResult( int rc )
{
if( !db )
if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED || rc==SQLITE_INTERRUPT || rc==SQLITE_IOERR )
return false;
return true;
}
// -----------------------------------------------------------------------------------------
SQLiteResult SQLiteInterface::query( const string q )
{
if( !db )
return SQLiteResult();
// char* errmsg = 0;
sqlite3_stmt* pStmt;
// Компилируем SQL запрос
sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL);
int rc = sqlite3_step(pStmt);
if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED || rc==SQLITE_INTERRUPT || rc==SQLITE_IOERR )
if( !checkResult(rc) && !wait(pStmt, SQLITE_ROW) )
{
if( !wait(pStmt, SQLITE_ROW) )
{
sqlite3_finalize(pStmt);
queryok=false;
return false;
}
sqlite3_finalize(pStmt);
queryok=false;
return SQLiteResult();
}
lastQ = q;
curStmt = pStmt;
// int cnum = sqlite3_column_count(pStmt);
/*
while( (rc = sqlite3_step(pStmt)) == SQLITE_ROW )
{
int coln = sqlite3_data_count(pStmt);
for( int j=0; j<coln; j++ )
{
}
}
*/
// sqlite3_finalize(pStmt);
queryok=true;
return true;
return SQLiteResult(pStmt,true);
}
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::wait( sqlite3_stmt* stmt, int result )
......@@ -174,12 +165,6 @@ const string SQLiteInterface::lastQuery()
return lastQ;
}
// -----------------------------------------------------------------------------------------
void SQLiteInterface::freeResult()
{
sqlite3_finalize(curStmt);
curStmt = 0;
}
// -----------------------------------------------------------------------------------------
int SQLiteInterface::insert_id()
{
if( !db )
......@@ -193,75 +178,74 @@ bool SQLiteInterface::isConnection()
return connected;
}
// -----------------------------------------------------------------------------------------
SQLiteInterface::iterator SQLiteInterface::begin()
int num_cols( SQLiteResult::iterator& it )
{
return SQLiteIterator(curStmt);
return it->size();
}
// -----------------------------------------------------------------------------------------
SQLiteInterface::iterator SQLiteInterface::end()
int as_int( SQLiteResult::iterator& it, int col )
{
return SQLiteIterator();
// if( col<0 || col >it->size() )
// return 0;
return uni_atoi( (*it)[col] );
}
// -----------------------------------------------------------------------------------------
SQLiteInterface::SQLiteIterator SQLiteInterface::SQLiteIterator::operator ++(int c)
double as_double( SQLiteResult::iterator& it, int col )
{
if( row == -1 || c<0 )
return *this;
if( c==0 )
c = 1;
for( int i=0; i<c; i++ )
{
int rc = sqlite3_step(stmt);
// cerr << "**** ++: rc=" << rc << " err: " << sqlite3_errmsg( sqlite3_db_handle(stmt) ) << endl;
if( rc != SQLITE_ROW )
{
row = -1;
break;
}
row++;
}
return *this;
return atof( ((*it)[col]).c_str() );
}
// -----------------------------------------------------------------------------------------
#if 0
SQLiteInterface::SQLiteIterator SQLiteInterface::SQLiteIterator::operator --()
string as_string( SQLiteResult::iterator& it, int col )
{
return ((*it)[col]);
}
#endif
// -----------------------------------------------------------------------------------------
std::string SQLiteInterface::SQLiteIterator::get_text( int col )
int as_int( SQLiteResult::COL::iterator& it )
{
return string( (char*)sqlite3_column_text(stmt,col) );
return uni_atoi( (*it) );
}
// -----------------------------------------------------------------------------------------
int SQLiteInterface::SQLiteIterator::get_int( int col )
double as_double( SQLiteResult::COL::iterator& it )
{
return sqlite3_column_int(stmt,col);
return atof( (*it).c_str() );
}
// -----------------------------------------------------------------------------------------
double SQLiteInterface::SQLiteIterator::get_double( int col )
std::string as_string( SQLiteResult::COL::iterator& it )
{
return sqlite3_column_double(stmt,col);
return (*it);
}
// -----------------------------------------------------------------------------------------
int SQLiteInterface::SQLiteIterator::get_num_cols()
#if 0
SQLiteResult::COL get_col( SQLiteResult::ROW::iterator& it )
{
return sqlite3_data_count(stmt);
return (*it);
}
#endif
// -----------------------------------------------------------------------------------------
bool SQLiteInterface::SQLiteIterator::is_end()
SQLiteResult::~SQLiteResult()
{
return ( row == -1 );
}
// -----------------------------------------------------------------------------------------
void SQLiteInterface::SQLiteIterator::free_result()
SQLiteResult::SQLiteResult( sqlite3_stmt* s, bool finalize )
{
sqlite3_finalize(stmt);
stmt = 0;
do
{
int n = sqlite3_data_count(s);
COL c;
for( int i=0; i<n; i++ )
{
char* p = (char*)sqlite3_column_text(s,i);
if( p )
c.push_back(p);
else
c.push_back("");
}
res.push_back(c);
}
while( sqlite3_step(s) == SQLITE_ROW );
if( finalize )
sqlite3_finalize(s);
}
// -----------------------------------------------------------------------------------------
......@@ -25,10 +25,14 @@
#define SQLiteInterface_H_
// ---------------------------------------------------------------------------
#include <string>
#include <list>
#include <vector>
#include <iostream>
#include <sqlite3.h>
#include "PassiveTimer.h"
// ----------------------------------------------------------------------------
class SQLiteResult;
// ----------------------------------------------------------------------------
class SQLiteInterface
{
public:
......@@ -45,7 +49,7 @@ class SQLiteInterface
inline void setOperationCheckPause( timeout_t msec ){ opCheckPause = msec; }
inline timeout_t getOperationCheckPause(){ return opCheckPause; }
bool query( const std::string q );
SQLiteResult query( const std::string q );
const std::string lastQuery();
bool insert( const std::string q );
......@@ -55,61 +59,15 @@ class SQLiteInterface
const std::string error();
void freeResult();
class SQLiteIterator
{
public:
SQLiteIterator( sqlite3_stmt* s ):stmt(s),row(0){}
SQLiteIterator():stmt(0),row(-1){}
~SQLiteIterator(){};
SQLiteIterator operator ++(int);
// SQLiteIterator operator --();
inline bool operator==(const SQLiteIterator& other) const
{
if( row == -1 && other.stmt==0 && other.row == -1 )
return true;
return ( stmt == other.stmt && row == other.row );
}
inline bool operator!=(const SQLiteIterator& other) const
{
return !operator==(other);
}
inline int row_num(){ return row; }
std::string get_text( int col );
int get_int( int col );
double get_double( int col );
int get_num_cols();
void free_result();
bool is_end();
protected:
sqlite3_stmt* stmt;
int row;
};
typedef SQLiteIterator iterator;
iterator begin();
iterator end();
protected:
bool wait( sqlite3_stmt* stmt, int result );
static bool checkResult( int rc );
private:
sqlite3* db;
sqlite3_stmt* curStmt;
// sqlite3_stmt* curStmt;
std::string lastQ;
bool queryok; // успешность текущего запроса
......@@ -119,5 +77,35 @@ class SQLiteInterface
timeout_t opCheckPause;
};
// ----------------------------------------------------------------------------------
class SQLiteResult
{
public:
SQLiteResult(){}
SQLiteResult( sqlite3_stmt* s, bool finalize=true );
~SQLiteResult();
typedef std::vector<std::string> COL;
typedef std::list<COL> ROW;
typedef ROW::iterator iterator;
inline iterator begin(){ return res.begin(); }
inline iterator end(){ return res.end(); }
inline operator bool(){ return !res.empty(); }
protected:
ROW res;
};
// ----------------------------------------------------------------------------
int num_cols( SQLiteResult::iterator& );
int as_int( SQLiteResult::iterator&, int col );
double as_double( SQLiteResult::iterator&, int col );
std::string as_text( SQLiteResult::iterator&, int col );
int as_int( SQLiteResult::COL::iterator& );
double as_double( SQLiteResult::COL::iterator& );
std::string as_string( SQLiteResult::COL::iterator& );
// ----------------------------------------------------------------------------
#endif
// ----------------------------------------------------------------------------------
......@@ -20,21 +20,22 @@ int main(int argc, char** argv)
stringstream q;
q << "SELECT * from main_history";
if( !db.query(q.str()) )
SQLiteResult r = db.query(q.str());
if( !r )
{
cerr << "db connect error: " << db.error() << endl;
return 1;
}
SQLiteInterface::iterator it = db.begin();
for( ; it!=db.end(); it++ )
for( SQLiteResult::iterator it=r.begin(); it!=r.end(); it++ )
{
cout << "get result: row=" << it.row_num() << " coln=" << it.get_num_cols() << endl;
for( int i=0; i<it.get_num_cols(); i++ )
cout << it.get_text(i) << "(" << it.get_double(i) << ") | ";
cout << "ROW: ";
SQLiteResult::COL col(*it);
for( SQLiteResult::COL::iterator cit = it->begin(); cit!=it->end(); cit++ )
cout << as_string(cit) << "(" << as_double(cit) << ") | ";
cout << endl;
}
db.freeResult();
db.close();
}
catch(Exception& ex)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment