sqlite3_db.cpp

Go to the documentation of this file.
00001 /*                                                              
00002  * A database abstraction layer for C++ and ACE framework
00003  * 
00004  * (C) 2006-2007 Thralling Penguin LLC. All rights reserved.
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                                                                 
00019  */
00020 #define ACE_BUILD_SVC_DLL
00021 #include <fstream>
00022 #include <iomanip>
00023 #include "sqlite3_db.h"
00024 #include "ace/Log_Msg.h"
00025 #include "ace/svc_export.h"
00026 #include "ace/OS_Memory.h"
00027 #include "ace/OS.h"
00028 #include "sqlite3.h"
00029 
00030 namespace DB
00031 {
00032 
00033 Sqlite3_ResultSet::~Sqlite3_ResultSet()
00034 {
00035     if (res_) {
00036         ACE_DEBUG((LM_ERROR,"Warning ResultSet wasn't closed or deleted.\n"));
00037     }
00038 }
00039 
00040 bool 
00041 Sqlite3_ResultSet::close(void)
00042 {
00043     int rc;
00044 
00045     if (!res_) return (false);
00046 
00047     // eat remaining rows, if there are some
00048     do {
00049         rc = sqlite3_step(res_);
00050     } while (rc != SQLITE_DONE && rc != SQLITE_ERROR && rc != SQLITE_MISUSE);
00051 
00052     sqlite3_finalize(res_);
00053     res_ = NULL;
00054     delete this;
00055 
00056     return (true);
00057 }
00058 
00059 bool 
00060 Sqlite3_ResultSet::next(void)
00061 {
00062     int rc;
00063 
00064     do {
00065         rc = sqlite3_step(res_);
00066         if (rc == SQLITE_BUSY) {
00067             sleep(1);
00068             continue;
00069         }
00070         if (rc == SQLITE_ROW) {
00071             return (true);
00072         }
00073     } while (rc != SQLITE_DONE && rc != SQLITE_ERROR && rc != SQLITE_MISUSE);
00074     return (false);
00075 }
00076 
00077 unsigned long 
00078 Sqlite3_ResultSet::recordCount(void) const
00079 {
00080     return (0); // not supported
00081 }
00082 
00083 unsigned int 
00084 Sqlite3_ResultSet::findColumn(const char *fld) const
00085 {
00086     unsigned int num_fields;
00087     unsigned int i;
00088     const char *field;
00089 
00090     num_fields = sqlite3_column_count(res_);
00091     for (i=0; i<num_fields; i++) {
00092         field = sqlite3_column_name(res_, i);
00093         if (ACE_OS::strcmp(field,fld) == 0) {
00094             return (i);
00095         }
00096     }
00097     return (i);
00098 }
00099 
00100 const char *
00101 Sqlite3_ResultSet::getString(const int idx) const
00102 {
00103     return ((const char *) sqlite3_column_text(res_, idx));
00104 }
00105 
00106 const int 
00107 Sqlite3_ResultSet::getInteger(const int idx) const
00108 {
00109     return ((const int) ACE_OS::atoi((const char *) sqlite3_column_text(res_, idx)));
00110 }
00111 
00112 const bool 
00113 Sqlite3_ResultSet::getBool(const int idx) const
00114 {
00115     register const char *v = (const char *) sqlite3_column_text(res_, idx);
00116     if (v && v[0] == '1') {
00117         return (true);
00118     }
00119     return (false);
00120 }
00121 
00122 const time_t 
00123 Sqlite3_ResultSet::getUnixTime(const int idx) const
00124 {
00125     struct tm tmp;
00126     register const char *v = (const char *) sqlite3_column_text(res_, idx);
00127     // ACE_DEBUG((LM_DEBUG, ACE_TEXT("Read UnixTime: %s\n"), row_[idx]));
00128 
00129     if (v) {
00130         // switch on the type of field
00131         // Basically, there are two types of returns I've seen
00132         // 1. has a hypen and is fully parseable
00133         // 2. has no hypen and is an older timestamp field
00134         // The others are raw DATE or TIME
00135         int Ypos = 0;
00136         int Mpos = 4;
00137         int Dpos = 6;
00138         int hpos = 8;
00139         int mpos = 10;
00140         int spos = 12;
00141         if (strchr(v, '-') != NULL) {
00142             ++Mpos;
00143             Dpos = 8;
00144             hpos = 11;
00145             mpos = 14;
00146             spos = 17;
00147         }
00148         tmp.tm_wday = 0;
00149         tmp.tm_yday = 0;
00150         tmp.tm_isdst = 0;
00151         tmp.tm_year = (((v[Ypos] - '0') * 1000) + ((v[Ypos+1] - '0') * 100) + ((v[Ypos+2] - '0') * 10) + (v[Ypos+3] - '0')) - 1900;
00152         tmp.tm_mon = (((v[Mpos] - '0') * 10) + (v[Mpos+1] - '0')) - 1; /* 0 - 11 */
00153         tmp.tm_mday = (((v[Dpos] - '0') * 10) + (v[Dpos+1] - '0')); /* 1 - 31 */
00154         tmp.tm_hour = (((v[hpos] - '0') * 10) + (v[hpos+1] - '0')) - 1; /* 0 - 23 */
00155         tmp.tm_min = (((v[mpos] - '0') * 10) + (v[mpos+1] - '0')); /* 0-59 */
00156         tmp.tm_sec = (((v[spos] - '0') * 10) + (v[spos+1] - '0')); /* 0-59 */
00157 
00158         /*
00159         ACE_DEBUG((LM_DEBUG, ACE_TEXT("y=%d m=%d d=%d h=%d m=%d s=%d\n"), 
00160                    tmp.tm_year,
00161                    tmp.tm_mon,
00162                    tmp.tm_mday,
00163                    tmp.tm_hour,
00164                    tmp.tm_min,
00165                    tmp.tm_sec));
00166         */
00167         return (mktime(&tmp));
00168     }
00169     return (0);
00170 }
00171 
00172 const double 
00173 Sqlite3_ResultSet::getDouble(const int idx) const
00174 {
00175     char *pEnd;
00176     return (ACE_OS::strtod((const char *) sqlite3_column_text(res_, idx), &pEnd));
00177 }
00178 
00179 const float 
00180 Sqlite3_ResultSet::getFloat(const int idx) const
00181 {
00182     return (atof((const char *) sqlite3_column_text(res_, idx)));
00183 }
00184 
00185 const long 
00186 Sqlite3_ResultSet::getLong(const int idx) const
00187 {
00188     return (atol((const char *) sqlite3_column_text(res_, idx)));
00189 }
00190 
00191 const short 
00192 Sqlite3_ResultSet::getShort(const int idx) const
00193 {
00194     return ((short) (ACE_OS::atoi((const char *) sqlite3_column_text(res_, idx))));
00195 }
00196 
00197 void *
00198 Sqlite3_ResultSet::operator new (size_t bytes)
00199 {
00200   return (::new char[bytes]);
00201 }
00202 #if defined (ACE_HAS_NEW_NOTHROW)
00203 void *
00204 Sqlite3_ResultSet::operator new (size_t bytes, const ACE_nothrow_t&)
00205 {
00206   return (::new (ACE_nothrow) char[bytes]);
00207 }
00208 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
00209 void
00210 Sqlite3_ResultSet::operator delete (void *p, const ACE_nothrow_t&) throw ()
00211 {
00212   delete [] static_cast <char *> (p);
00213 }
00214 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
00215 #endif
00216 void
00217 Sqlite3_ResultSet::operator delete (void *ptr)
00218 {
00219   delete [] static_cast <char *> (ptr);
00220 }
00221 
00222 bool
00223 Sqlite3_Connection::open(const char *database, const char *host, const int port, const char *user, const char *pass)
00224 {
00225     if (sqlite3_open(database, &db_) != SQLITE_OK) {
00226         db_ = NULL;
00227         return (false);
00228     }
00229     return (true);
00230 }
00231 
00232 bool 
00233 Sqlite3_Connection::close(void)
00234 {
00235     if (!db_) return (false);
00236     if (sqlite3_close(db_) != SQLITE_OK) {
00237         return (false);
00238     }
00239     db_ = NULL;
00240     return (true);
00241 }
00242 
00243 bool
00244 Sqlite3_Connection::isConnected(void)
00245 {
00246     if (!db_) return (false);
00247     return (true);
00248 }
00249 
00250 bool 
00251 Sqlite3_Connection::execute(const char *sql)
00252 {
00253     bool ret = false;
00254     char *err = NULL;
00255 
00256     if (!db_) return (ret);
00257 
00258     if (sqlite3_exec(db_, sql, NULL, NULL, &err) == SQLITE_OK) {
00259         ret = true;
00260     }
00261     if (err) {
00262         sqlite3_free(err);
00263     }
00264     return (ret);
00265 }
00266 
00267 DB::ResultSet * 
00268 Sqlite3_Connection::executeQuery(const char *sql)
00269 {
00270     sqlite3_stmt *vm = NULL;
00271     const char *tail = NULL;
00272 
00273     if (!db_) return (false);
00274 
00275     if (sqlite3_prepare(db_, sql, -1, &vm, &tail) != SQLITE_OK) {
00276         return (0);
00277     }
00278 
00279     DB::ResultSet *c = 0;
00280     ACE_NEW_RETURN (c, DB::Sqlite3_ResultSet(vm), 0);
00281     return (c);
00282 }
00283 
00284 char *
00285 Sqlite3_Connection::escape(const char *str)
00286 {
00287     /* this is overly complex so that valgrind doesn't report a mismatched
00288      * delete, free, delete[].
00289      */
00290     char *esc = sqlite3_mprintf("\'%q\'", str);
00291     char *ret = new char[strlen(esc) + 1];
00292     strcpy(ret, esc);
00293     free(esc);
00294     return (ret);
00295 
00296 }
00297 
00298 const char *
00299 Sqlite3_Connection::unixtimeToSql(const time_t val)
00300 {
00301     char *buf = new char[22];
00302     struct tm *tmp = new struct tm;
00303     buf[0] = '\'';
00304     ACE_OS::strftime(buf+1, 20, "%Y-%m-%d %H:%M:%S", ACE_OS::localtime_r(&val, tmp));
00305     buf[20] = '\'';
00306     buf[21] = 0;
00307     delete tmp;
00308     return (buf);
00309 }
00310 
00311 const unsigned long 
00312 Sqlite3_Connection::insertId(void)
00313 {
00314     return ((const unsigned long) sqlite3_last_insert_rowid(db_));
00315 }
00316 
00317 bool 
00318 Sqlite3_Connection::beginTrans(void)
00319 {
00320     if (!db_) return (false);
00321     return (execute("BEGIN TRANSACTION"));
00322 }
00323 
00324 bool
00325 Sqlite3_Connection::commitTrans(void)
00326 {
00327     if (!db_) return (false);
00328     return (execute("COMMIT TRANSACTION"));
00329 }
00330 
00331 bool
00332 Sqlite3_Connection::rollbackTrans(void)
00333 {
00334     if (!db_) return (false);
00335     return (execute("ROLLBACK TRANSACTION"));
00336 }
00337 
00338 bool 
00339 Sqlite3_Connection::setTransactionMode(const enum TRANS_MODE mode)
00340 {
00341     const char *sql = "";
00342 
00343     switch (mode) {
00344     case READ_UNCOMMITTED:
00345         sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED";
00346         break;
00347     case READ_COMMITTED:
00348         sql = "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED";
00349         break;
00350     case REPEATABLE_READ:
00351         sql = "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ";
00352         break;
00353     case SERIALIZABLE:
00354         sql = "SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE";
00355         break;
00356     default:
00357         return false;
00358     }
00359     return (execute(sql));
00360 }
00361 
00362 unsigned int 
00363 Sqlite3_Connection::errorno(void) const
00364 {
00365     return ((unsigned int) sqlite3_errcode(db_));
00366 }
00367 
00368 const char *
00369 Sqlite3_Connection::errormsg(void) const
00370 {
00371     return (sqlite3_errmsg(db_));
00372 }
00373 
00374 const char *
00375 Sqlite3_Connection::version(void) const
00376 {
00377     static char ret[256];
00378     ACE_OS::snprintf(ret, 256, "Sqlite3 Driver v0.1 using %s", sqlite3_libversion());
00379     return ((const char *) ret);
00380 }
00381 
00382 void *
00383 Sqlite3_Connection::operator new (size_t bytes)
00384 {
00385   return (::new char[bytes]);
00386 }
00387 #if defined (ACE_HAS_NEW_NOTHROW)
00388 void *
00389 Sqlite3_Connection::operator new (size_t bytes, const ACE_nothrow_t&)
00390 {
00391   return (::new (ACE_nothrow) char[bytes]);
00392 }
00393 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
00394 void
00395 Sqlite3_Connection::operator delete (void *p, const ACE_nothrow_t&) throw ()
00396 {
00397   delete [] static_cast <char *> (p);
00398 }
00399 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
00400 #endif
00401 void
00402 Sqlite3_Connection::operator delete (void *ptr)
00403 {
00404   delete [] static_cast <char *> (ptr);
00405 }
00406 
00407 // Returns the Newsweek class pointer.
00408 // The ACE_BUILD_SVC_DLL and ACE_Svc_Export directives are necessary to
00409 // take care of exporting the function for Win32 platforms.
00410 //
00411 
00412 extern "C" ACE_Svc_Export Connection *create_connection (void);
00413 
00414 DB::Connection *
00415 create_connection (void)
00416 {
00417   DB::Sqlite3_Connection *c = 0;
00418   ACE_NEW_RETURN (c, DB::Sqlite3_Connection, 0);
00419   return (c);
00420 }
00421 
00422 }
00423 

Generated on Tue Apr 24 18:59:42 2007 for DbAbstract by  doxygen 1.4.7