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 ) ...@@ -108,6 +108,7 @@ void DBServer_SQLite::sysCommand( UniSetTypes::SystemMessage *sm )
case SystemMessage::Finish: case SystemMessage::Finish:
{ {
activate = false; activate = false;
// db->freeResult();
db->close(); db->close();
} }
break; break;
...@@ -115,6 +116,7 @@ void DBServer_SQLite::sysCommand( UniSetTypes::SystemMessage *sm ) ...@@ -115,6 +116,7 @@ void DBServer_SQLite::sysCommand( UniSetTypes::SystemMessage *sm )
case SystemMessage::FoldUp: case SystemMessage::FoldUp:
{ {
activate = false; activate = false;
// db->freeResult();
db->close(); db->close();
} }
break; break;
...@@ -179,6 +181,7 @@ void DBServer_SQLite::parse( UniSetTypes::ConfirmMessage* cem ) ...@@ -179,6 +181,7 @@ void DBServer_SQLite::parse( UniSetTypes::ConfirmMessage* cem )
{ {
if( unideb.debugging(Debug::CRIT) ) if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << myname << "(update_confirm): db error: "<< db->error() << endl; unideb[Debug::CRIT] << myname << "(update_confirm): db error: "<< db->error() << endl;
// db->freeResult();
} }
} }
catch( Exception& ex ) catch( Exception& ex )
...@@ -231,7 +234,10 @@ bool DBServer_SQLite::writeToBase( const string& query ) ...@@ -231,7 +234,10 @@ bool DBServer_SQLite::writeToBase( const string& query )
// см. SQLiteInterface::query. // см. SQLiteInterface::query.
string err(db->error()); string err(db->error());
if( err.empty() ) if( err.empty() )
{
// db->freeResult();
return true; return true;
}
return false; return false;
} }
...@@ -243,6 +249,7 @@ void DBServer_SQLite::flushBuffer() ...@@ -243,6 +249,7 @@ void DBServer_SQLite::flushBuffer()
// Сперва пробуем очистить всё что накопилось в очереди до этого... // Сперва пробуем очистить всё что накопилось в очереди до этого...
while( !qbuf.empty() ) while( !qbuf.empty() )
{ {
#if 0
db->query( qbuf.front() ); db->query( qbuf.front() );
// Дело в том что на INSERT И UPDATE запросы // Дело в том что на INSERT И UPDATE запросы
...@@ -250,13 +257,14 @@ void DBServer_SQLite::flushBuffer() ...@@ -250,13 +257,14 @@ void DBServer_SQLite::flushBuffer()
// отдельно проверять действительно ли произошла ошибка // отдельно проверять действительно ли произошла ошибка
// см. SQLiteInterface::query. // см. SQLiteInterface::query.
string err(db->error()); string err(db->error());
if( err.empty() )
if( err.empty() && unideb.debugging(Debug::CRIT) ) db->freeResult();
else if( unideb.debugging(Debug::CRIT) )
{ {
unideb[Debug::CRIT] << myname << "(writeToBase): error: " << err << unideb[Debug::CRIT] << myname << "(writeToBase): error: " << err <<
" lost query: " << qbuf.front() << endl; " lost query: " << qbuf.front() << endl;
} }
#endif
qbuf.pop(); qbuf.pop();
} }
} }
...@@ -291,6 +299,7 @@ void DBServer_SQLite::parse( UniSetTypes::SensorMessage *si ) ...@@ -291,6 +299,7 @@ void DBServer_SQLite::parse( UniSetTypes::SensorMessage *si )
{ {
if( unideb.debugging(Debug::CRIT) ) if( unideb.debugging(Debug::CRIT) )
unideb[Debug::CRIT] << myname << "(insert) sensor msg error: "<< db->error() << endl; unideb[Debug::CRIT] << myname << "(insert) sensor msg error: "<< db->error() << endl;
// db->freeResult();
} }
} }
catch( Exception& ex ) catch( Exception& ex )
......
...@@ -32,7 +32,6 @@ using namespace UniSetTypes; ...@@ -32,7 +32,6 @@ using namespace UniSetTypes;
SQLiteInterface::SQLiteInterface(): SQLiteInterface::SQLiteInterface():
db(0), db(0),
curStmt(0),
lastQ(""), lastQ(""),
queryok(false), queryok(false),
connected(false), connected(false),
...@@ -53,7 +52,7 @@ bool SQLiteInterface::connect( const string dbfile ) ...@@ -53,7 +52,7 @@ bool SQLiteInterface::connect( const string dbfile )
{ {
int rc = sqlite3_open(dbfile.c_str(), &db); 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; cerr << "SQLiteInterface::connect): rc=" << rc << " error: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db); sqlite3_close(db);
...@@ -86,17 +85,19 @@ bool SQLiteInterface::insert( const string q ) ...@@ -86,17 +85,19 @@ bool SQLiteInterface::insert( const string q )
sqlite3_stmt* pStmt; sqlite3_stmt* pStmt;
// Компилируем SQL запрос // Компилируем 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); 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;
sqlite3_finalize(pStmt); return false;
queryok=false;
return false;
}
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
...@@ -104,45 +105,35 @@ bool SQLiteInterface::insert( const string q ) ...@@ -104,45 +105,35 @@ bool SQLiteInterface::insert( const string q )
return true; 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 false;
return true;
}
// -----------------------------------------------------------------------------------------
SQLiteResult SQLiteInterface::query( const string q )
{
if( !db )
return SQLiteResult();
// char* errmsg = 0; // char* errmsg = 0;
sqlite3_stmt* pStmt; sqlite3_stmt* pStmt;
// Компилируем SQL запрос // Компилируем SQL запрос
sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL); sqlite3_prepare(db, q.c_str(), -1, &pStmt, NULL);
int rc = sqlite3_step(pStmt); 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;
sqlite3_finalize(pStmt); return SQLiteResult();
queryok=false;
return false;
}
} }
lastQ = q; 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; queryok=true;
return true; return SQLiteResult(pStmt,true);
} }
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
bool SQLiteInterface::wait( sqlite3_stmt* stmt, int result ) bool SQLiteInterface::wait( sqlite3_stmt* stmt, int result )
...@@ -174,12 +165,6 @@ const string SQLiteInterface::lastQuery() ...@@ -174,12 +165,6 @@ const string SQLiteInterface::lastQuery()
return lastQ; return lastQ;
} }
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
void SQLiteInterface::freeResult()
{
sqlite3_finalize(curStmt);
curStmt = 0;
}
// -----------------------------------------------------------------------------------------
int SQLiteInterface::insert_id() int SQLiteInterface::insert_id()
{ {
if( !db ) if( !db )
...@@ -193,75 +178,74 @@ bool SQLiteInterface::isConnection() ...@@ -193,75 +178,74 @@ bool SQLiteInterface::isConnection()
return connected; 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 atof( ((*it)[col]).c_str() );
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;
} }
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
#if 0 string as_string( SQLiteResult::iterator& it, int col )
SQLiteInterface::SQLiteIterator SQLiteInterface::SQLiteIterator::operator --()
{ {
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); do
stmt = 0; {
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 @@ ...@@ -25,10 +25,14 @@
#define SQLiteInterface_H_ #define SQLiteInterface_H_
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#include <string> #include <string>
#include <list>
#include <vector>
#include <iostream> #include <iostream>
#include <sqlite3.h> #include <sqlite3.h>
#include "PassiveTimer.h" #include "PassiveTimer.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class SQLiteResult;
// ----------------------------------------------------------------------------
class SQLiteInterface class SQLiteInterface
{ {
public: public:
...@@ -45,7 +49,7 @@ class SQLiteInterface ...@@ -45,7 +49,7 @@ class SQLiteInterface
inline void setOperationCheckPause( timeout_t msec ){ opCheckPause = msec; } inline void setOperationCheckPause( timeout_t msec ){ opCheckPause = msec; }
inline timeout_t getOperationCheckPause(){ return opCheckPause; } inline timeout_t getOperationCheckPause(){ return opCheckPause; }
bool query( const std::string q ); SQLiteResult query( const std::string q );
const std::string lastQuery(); const std::string lastQuery();
bool insert( const std::string q ); bool insert( const std::string q );
...@@ -55,61 +59,15 @@ class SQLiteInterface ...@@ -55,61 +59,15 @@ class SQLiteInterface
const std::string error(); 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: protected:
bool wait( sqlite3_stmt* stmt, int result ); bool wait( sqlite3_stmt* stmt, int result );
static bool checkResult( int rc );
private: private:
sqlite3* db; sqlite3* db;
sqlite3_stmt* curStmt; // sqlite3_stmt* curStmt;
std::string lastQ; std::string lastQ;
bool queryok; // успешность текущего запроса bool queryok; // успешность текущего запроса
...@@ -119,5 +77,35 @@ class SQLiteInterface ...@@ -119,5 +77,35 @@ class SQLiteInterface
timeout_t opCheckPause; 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 #endif
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
...@@ -20,21 +20,22 @@ int main(int argc, char** argv) ...@@ -20,21 +20,22 @@ int main(int argc, char** argv)
stringstream q; stringstream q;
q << "SELECT * from main_history"; 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; cerr << "db connect error: " << db.error() << endl;
return 1; return 1;
} }
SQLiteInterface::iterator it = db.begin(); for( SQLiteResult::iterator it=r.begin(); it!=r.end(); it++ )
for( ; it!=db.end(); it++ )
{ {
cout << "get result: row=" << it.row_num() << " coln=" << it.get_num_cols() << endl; cout << "ROW: ";
for( int i=0; i<it.get_num_cols(); i++ ) SQLiteResult::COL col(*it);
cout << it.get_text(i) << "(" << it.get_double(i) << ") | "; for( SQLiteResult::COL::iterator cit = it->begin(); cit!=it->end(); cit++ )
cout << as_string(cit) << "(" << as_double(cit) << ") | ";
cout << endl; cout << endl;
} }
db.freeResult();
db.close(); db.close();
} }
catch(Exception& ex) 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