Back to index

lshw  02.16
db.cc
Go to the documentation of this file.
00001 #include <string.h>
00002 #include <string>
00003 #include <stdexcept>
00004 #include <sqlite3.h>
00005 
00006 #include "db.h"
00007 
00008 using namespace sqlite;
00009 using namespace std;
00010 
00011 namespace sqlite {
00012 
00013 class exception : public std::runtime_error
00014 {
00015 public:
00016        exception(sqlite3 *db):
00017               runtime_error("SQLite error: " + string(sqlite3_errmsg(db)))
00018        {
00019        }
00020 
00021        exception(const char * msg):
00022               runtime_error(msg)
00023        {
00024        }
00025 };
00026 
00027 }; // namespace sqlite
00028 
00029 struct sqlite::database_i
00030 {
00031   sqlite3* connection;
00032 
00033   database_i()
00034   {
00035     connection = NULL;
00036   }
00037 };
00038 
00039 database::database(const std::string & filename):
00040        implementation(NULL)
00041 {
00042   implementation = new database_i;
00043 
00044   if(implementation)
00045     if(sqlite3_open(filename.c_str(), &implementation->connection) != SQLITE_OK)
00046       throw exception(implementation->connection);
00047 }
00048 
00049 database::database(const database & db)
00050 {
00051   implementation = new database_i;
00052 
00053   if(implementation && db.implementation)
00054     *implementation = *(db.implementation);
00055 }
00056 
00057 database::~database()
00058 {
00059   if(implementation)
00060   {
00061     sqlite3_close(implementation->connection);
00062     delete implementation;
00063   }
00064 }
00065 
00066 void database::execute(const string & sql)
00067 {
00068   if(implementation)
00069   {
00070     statement s(*this, sql);
00071     s.execute();
00072   }
00073 }
00074 
00075 struct sqlite::value_i
00076 {
00077   unsigned int ref;
00078   type value_type;
00079   union
00080   {
00081     long long integer_value;
00082     double real_value;
00083     string *text_value;
00084   };
00085 
00086   value_i()
00087   {
00088     value_type = null;
00089     ref = 1;
00090   }
00091 
00092   ~value_i()
00093   {
00094     if((value_type == text) && text_value)
00095       delete text_value;
00096   }
00097 };
00098 
00099 value::value(const std::string & s)
00100 {
00101   implementation = new value_i;
00102 
00103   if(implementation)
00104   {
00105     implementation->value_type = text;
00106     implementation->text_value = new string(s);
00107   }
00108 }
00109 
00110 value::value(const char * s)
00111 {
00112   implementation = new value_i;
00113 
00114   if(implementation)
00115   {
00116     implementation->value_type = text;
00117     implementation->text_value = new string(s);
00118   }
00119 }
00120 
00121 value::value(long long l)
00122 {
00123   implementation = new value_i;
00124 
00125   if(implementation)
00126   {
00127     implementation->value_type = integer;
00128     implementation->integer_value = l;
00129   }
00130 }
00131 
00132 value::value(double d)
00133 {
00134   implementation = new value_i;
00135 
00136   if(implementation)
00137   {
00138     implementation->value_type = real;
00139     implementation->real_value = d;
00140   }
00141 }
00142 
00143 value::value()
00144 {
00145   implementation = new value_i;
00146 }
00147 
00148 value::value(const value & v)
00149 {
00150   implementation = v.implementation;
00151 
00152   if(implementation) implementation->ref++;
00153 }
00154 
00155 value::~value()
00156 {
00157   if(implementation)
00158   {
00159     implementation->ref--;
00160     if(implementation->ref<=0) delete implementation;
00161   }
00162 }
00163 
00164 value & value::operator =(const value & v)
00165 {
00166   if(&v == this) return *this; // self-affectation
00167 
00168   if(implementation)
00169   {
00170     implementation->ref--;
00171     if(implementation->ref<=0) delete implementation;
00172   }
00173 
00174   implementation = v.implementation;
00175 
00176   if(implementation) implementation->ref++;
00177 
00178   return *this;
00179 }
00180 
00181 type value::getType() const
00182 {
00183   if(implementation)
00184     return implementation->value_type;
00185   else
00186     return null;
00187 }
00188 
00189 string value::asText() const
00190 {
00191   if(!implementation || (implementation->value_type == null))
00192     throw exception("Can't convert NULL value to text");
00193 
00194   switch(implementation->value_type)
00195   {
00196     case text:
00197     case blob:
00198        return *(implementation->text_value);
00199     default:
00200         throw exception("Can't convert value to text");
00201   }
00202 
00203   throw exception("Can't convert value to text");
00204 }
00205 
00206 long long value::asInteger() const
00207 {
00208   if(!implementation || (implementation->value_type == null))
00209     throw exception("Can't convert NULL value to integer");
00210 
00211   switch(implementation->value_type)
00212   {
00213     case integer:
00214        return implementation->integer_value;
00215     default:
00216         throw exception("Can't convert value to integer");
00217   }
00218 }
00219 
00220 double value::asReal() const
00221 {
00222   if(!implementation || (implementation->value_type == null))
00223     throw exception("Can't convert NULL value to real");
00224 
00225   switch(implementation->value_type)
00226   {
00227     case real:
00228        return implementation->real_value;
00229     default:
00230        throw exception("Can't convert value to real");
00231   }
00232 
00233 }
00234 
00235 ostream & value::print(std::ostream & out) const
00236 {
00237   if(!implementation)
00238     out << "NULL";
00239   else
00240   switch(implementation->value_type)
00241   {
00242     case integer:
00243        out << implementation->integer_value;
00244        break;
00245     case real:
00246        out << implementation->real_value;
00247        break;
00248     case text:
00249        out << *(implementation->text_value);
00250        break;
00251     case blob:
00252        out << "BLOB";
00253        break;
00254     case null:
00255        out << "NULL";
00256        break;
00257 
00258   }
00259 
00260   return out;
00261 }
00262 
00263 struct sqlite::statement_i
00264 {
00265   database *db;
00266   sqlite3_stmt *stmt;
00267 };
00268 
00269 statement::statement(database & db, const std::string & s)
00270 {
00271   implementation = new statement_i;
00272 
00273   if(!implementation)
00274     throw exception("memory exhausted");
00275 
00276   implementation->db = &db;
00277   if(!db.implementation)
00278     throw exception("invalid database");
00279 
00280   if(sqlite3_prepare(db.implementation->connection, s.c_str(), -1, &implementation->stmt, NULL) != SQLITE_OK)
00281     throw exception(db.implementation->connection);
00282 }
00283 
00284 statement::~statement()
00285 {
00286   if(implementation)
00287   {
00288     if(implementation->stmt)
00289       sqlite3_finalize(implementation->stmt);
00290 
00291     delete implementation;
00292   }
00293 }
00294 
00295 void statement::prepare(const std::string & s)
00296 {
00297   if(implementation)
00298   {
00299     if(implementation->stmt)
00300       sqlite3_finalize(implementation->stmt);
00301   }
00302   else
00303     implementation = new statement_i;
00304 
00305   if(!implementation)
00306     throw exception("memory exhausted");
00307 
00308   if(sqlite3_prepare(implementation->db->implementation->connection, s.c_str(), -1, &implementation->stmt, NULL) != SQLITE_OK)
00309     throw exception(implementation->db->implementation->connection);
00310 }
00311 
00312 void statement::bind(int index, const value & v)
00313 {
00314   if(!implementation)
00315     throw exception("undefined statement");
00316 
00317   switch(v.getType())
00318   {
00319     case null:
00320         if(sqlite3_bind_null(implementation->stmt, index) != SQLITE_OK)
00321          throw exception(implementation->db->implementation->connection);
00322        break;
00323     case text:
00324         if(sqlite3_bind_text(implementation->stmt, index, v.asText().c_str(), -1, SQLITE_TRANSIENT) != SQLITE_OK)
00325          throw exception(implementation->db->implementation->connection);
00326        break;
00327     case blob:
00328        {
00329           string blob = v.asText();
00330           if(sqlite3_bind_text(implementation->stmt, index, blob.data(), blob.size(), SQLITE_TRANSIENT) != SQLITE_OK)
00331            throw exception(implementation->db->implementation->connection);
00332          break;
00333        }
00334     case integer:
00335         if(sqlite3_bind_int64(implementation->stmt, index, v.asInteger()) != SQLITE_OK)
00336          throw exception(implementation->db->implementation->connection);
00337        break;
00338     case real:
00339         if(sqlite3_bind_double(implementation->stmt, index, v.asReal()) != SQLITE_OK)
00340          throw exception(implementation->db->implementation->connection);
00341        break;
00342     default:
00343        throw exception("unknown type");
00344   }
00345 }
00346 
00347 bool statement::step()
00348 {
00349   if(!implementation)
00350     throw exception("undefined statement");
00351 
00352   int result = sqlite3_step(implementation->stmt);
00353 
00354   if(result == SQLITE_DONE) return false;
00355   if(result == SQLITE_ROW) return true;
00356 
00357   throw exception(implementation->db->implementation->connection);
00358 }
00359 
00360 void statement::execute()
00361 {
00362   while(step());
00363 }
00364 
00365 void statement::reset()
00366 {
00367   if(!implementation)
00368     throw exception("undefined statement");
00369 
00370   sqlite3_reset(implementation->stmt);    // ignore return value
00371 }
00372 
00373 int statement::columns() const
00374 {
00375   if(!implementation)
00376     throw exception("undefined statement");
00377 
00378   return sqlite3_column_count(implementation->stmt);
00379 }
00380 
00381 value statement::column(unsigned int i) const
00382 {
00383   if(!implementation)
00384     throw exception("undefined statement");
00385 
00386   switch(sqlite3_column_type(implementation->stmt, i))
00387   {
00388     case SQLITE_INTEGER:
00389        return value(sqlite3_column_int64(implementation->stmt, i));
00390     case SQLITE_FLOAT:
00391        return value(sqlite3_column_double(implementation->stmt, i));
00392     case SQLITE_TEXT:
00393        return value((const char*)sqlite3_column_text(implementation->stmt, i));
00394     case SQLITE_BLOB:
00395     case SQLITE_NULL:
00396     default:
00397        return value();
00398   }
00399 }
00400 
00401 value statement::column(const string & name) const
00402 {
00403   if(!implementation)
00404     throw exception("undefined statement");
00405 
00406   for(int i=0; i<columns(); i++)
00407     if(strcasecmp(sqlite3_column_name(implementation->stmt, i), name.c_str())==0)
00408       return column(i);
00409 
00410   return value();
00411 }
00412 
00413 value statement::operator[](unsigned int i) const
00414 {
00415   return column(i);
00416 }
00417 
00418 value statement::operator[](const string & i) const
00419 {
00420   return column(i);
00421 }