1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
#include "SqliteDB.h"
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <unistd.h> //for sleep()
//A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
SqliteDBexception::SqliteDBexception() throw() {}
SqliteDBexception::SqliteDBexception(const char* s) throw() {msg = s;}
SqliteDBexception::SqliteDBexception (const string s) throw() {msg = s;}
SqliteDBexception::~SqliteDBexception() throw() {}
const char* SqliteDBexception::what() const throw() {return msg.c_str();}
SqliteDB::SqliteDB(): dbPtr(NULL)
{}
SqliteDB::~SqliteDB()
{
close();
}
void SqliteDB::close()
{
sqlite3_close(dbPtr);
}
int SqliteDB::last_insert_rowid()
{
return sqlite3_last_insert_rowid(dbPtr);
}
/**
* @throw SqliteDBexception if cannot open db.
*/
void SqliteDB::open(const char *filename)
{
if( sqlite3_open(filename, &dbPtr))
{
throw SqliteDBexception("open::Cannot open database file");
}//true = could not open db. false = no errors
}
void SqliteDB::open(const string &filename)
{
open(filename.c_str());
}
//this is used for debugging.
//print the resutls from query()
void SqliteDB::printResults(const vector<vector<string> > &v)
{
for(vector<vector<string> >::const_iterator i = v.begin(); i != v.end(); ++i)
{
for(vector<string>::const_iterator j = (*i).begin(); j != (*i).end(); ++j)
cout << *j << "\t";
cout << endl;
}
}
/**
* Returns the results of an SQL query as an array of strings.
* Null values are returned as the string "NULL"
* @parm query: sql string to run
* @return 2d array of results w/o any table heading.
*/
vector<vector<string> > SqliteDB::query(const char* query)
{
sqlite3_stmt *statement;
vector<vector<string> > results;
int queryErrorCode;
queryErrorCode =sqlite3_prepare_v2(dbPtr, query, -1, &statement, 0);
while ( queryErrorCode == SQLITE_BUSY)
{
cout << "Database is busy, sleeping for 5sec." << endl;
sleep(5);
cout << "Re-running sql:" << query << endl;
queryErrorCode = sqlite3_prepare_v2(dbPtr, query, -1, &statement, 0);
}//while db is busy.
if(queryErrorCode == SQLITE_OK)
{
int cols = sqlite3_column_count(statement);
//The commented-out line can be used to get the header row (the names of the columns)
//const char *sqlite3_column_name(sqlite3_stmt*, int N); gets header infor for nth col(starting from zero???).
int result = 0;
while(true)
{
result = sqlite3_step(statement);
if(result == SQLITE_ROW)
{
vector<string> values;
for(int col = 0; col < cols; col++)
{
char *resultsPtr = (char*)sqlite3_column_text(statement, col);
if ( resultsPtr)
values.push_back(resultsPtr);
else
values.push_back("NULL");
}//for every col in the current row.
results.push_back(values);
}//if there are results
else
{
break;
}
}//while there are more rows
sqlite3_finalize(statement);//free up the memory.
}//if no errors
else
{
string error = sqlite3_errmsg(dbPtr);
stringstream s;
s << "SqliteDB ERROR:: ." << query << ". " << error << endl;
cout << s.str().c_str() << endl;
throw SqliteDBexception(s.str());
}//else there was errors running the sql statment
return results;
}//query
vector<vector<string> > SqliteDB::query(const string &q)
{
return query(q.c_str());
}
/**
* For queries that return 1 int (example: select count(*) form...where...)
*/
int SqliteDB::queryAsInteger(const char* q)
{
vector<vector<string> > result = query(q);
if ( result.size() != 1 && result[0].size() !=1 )
throw SqliteDBexception("queryAsInteger::Query contains more than 1 result");
return atoi(result[0][0].c_str());
}
/**
* For queries that return 1 floating-point number (example: select avg(*) form...where...)
*/
double SqliteDB::queryAsFloat(const char* q)
{
vector<vector<string> > result = query(q);
if ( result.size() != 1 && result[0].size() !=1 )
throw SqliteDBexception("queryAsFloat::Query contains more than 1 result");
return atof(result[0][0].c_str());
}
/**
* For queries that return 1 column of numerical data.
*/
vector<double> SqliteDB::queryAsFloatArray(const char *q)
{
vector<vector<string> > result = query(q);
vector<double> ans;
ans.resize(result.size());
for(int i = 0; i < result.size(); ++i)
{
if ( result[i].size() != 1)
throw SqliteDBexception("queryAsFloatArray::Query contains more than 1 column");
if( result[i][0].compare("NULL") == 0)
ans[i] = 0.0;
else
ans[i] = atof(result[i][0].c_str());
}//for i.
return ans;
}//queryAsFloatArray
|