00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef _WIN32
00033 #pragma warning(disable:4786)
00034 #endif
00035
00036 #include <string>
00037 #include <map>
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <sqlite3.h>
00042
00043 #include "Database.h"
00044 #include "Query.h"
00045
00046
00047 #ifdef SQLITEW_NAMESPACE
00048 namespace SQLITEW_NAMESPACE {
00049 #endif
00050
00051
00052 Query::Query(Database& dbin)
00053 : m_db(dbin)
00054 ,odb(dbin.grabdb())
00055 ,res(NULL)
00056 ,row(false)
00057 ,cache_rc(0)
00058 ,cache_rc_valid(false)
00059 ,m_row_count(0)
00060 ,m_num_cols(0)
00061 {
00062 }
00063
00064
00065 Query::Query(Database& dbin,const std::string& sql)
00066 : m_db(dbin)
00067 ,odb(dbin.grabdb())
00068 ,res(NULL)
00069 ,row(false)
00070 ,cache_rc(0)
00071 ,cache_rc_valid(false)
00072 ,m_row_count(0)
00073 ,m_num_cols(0)
00074 {
00075 execute(sql);
00076 }
00077
00078
00079 Query::~Query()
00080 {
00081 if (res)
00082 {
00083 GetDatabase().error(*this, "sqlite3_finalize in destructor");
00084 sqlite3_finalize(res);
00085 }
00086 if (odb)
00087 {
00088 m_db.freedb(odb);
00089 }
00090 }
00091
00092
00093 Database& Query::GetDatabase() const
00094 {
00095 return m_db;
00096 }
00097
00098
00099
00100
00101
00102
00103 bool Query::execute(const std::string& sql)
00104 {
00105
00106 m_last_query = sql;
00107 if (odb && res)
00108 {
00109 GetDatabase().error(*this, "execute: query busy");
00110 }
00111 if (odb && !res)
00112 {
00113 const char *s = NULL;
00114 int rc = sqlite3_prepare(odb -> db, sql.c_str(), sql.size(), &res, &s);
00115 if (rc != SQLITE_OK)
00116 {
00117 GetDatabase().error(*this, "execute: prepare query failed");
00118 return false;
00119 }
00120 if (!res)
00121 {
00122 GetDatabase().error(*this, "execute: query failed");
00123 return false;
00124 }
00125 rc = sqlite3_step(res);
00126 sqlite3_finalize(res);
00127 res = NULL;
00128 switch (rc)
00129 {
00130 case SQLITE_BUSY:
00131 GetDatabase().error(*this, "execute: database busy");
00132 return false;
00133 case SQLITE_DONE:
00134 case SQLITE_ROW:
00135 return true;
00136 case SQLITE_ERROR:
00137 GetDatabase().error(*this, sqlite3_errmsg(odb -> db));
00138 return false;
00139 case SQLITE_MISUSE:
00140 GetDatabase().error(*this, "execute: database misuse");
00141 return false;
00142 }
00143 GetDatabase().error(*this, "execute: unknown result code");
00144 }
00145 return false;
00146 }
00147
00148
00149
00150
00151
00152 sqlite3_stmt *Query::get_result(const std::string& sql)
00153 {
00154
00155 m_last_query = sql;
00156 if (odb && res)
00157 {
00158 GetDatabase().error(*this, "get_result: query busy");
00159 }
00160 if (odb && !res)
00161 {
00162 const char *s = NULL;
00163 int rc = sqlite3_prepare(odb -> db, sql.c_str(), sql.size(), &res, &s);
00164 if (rc != SQLITE_OK)
00165 {
00166 GetDatabase().error(*this, "get_result: prepare query failed");
00167 return NULL;
00168 }
00169 if (!res)
00170 {
00171 GetDatabase().error(*this, "get_result: query failed");
00172 return NULL;
00173 }
00174
00175 {
00176 int i = 0;
00177 do
00178 {
00179 const char *p = sqlite3_column_name(res, i);
00180 if (!p)
00181 break;
00182 m_nmap[p] = ++i;
00183 } while (true);
00184 m_num_cols = i;
00185 }
00186 cache_rc = sqlite3_step(res);
00187 cache_rc_valid = true;
00188 m_row_count = (cache_rc == SQLITE_ROW) ? 1 : 0;
00189 }
00190 return res;
00191 }
00192
00193
00194 void Query::free_result()
00195 {
00196 if (odb && res)
00197 {
00198 sqlite3_finalize(res);
00199 res = NULL;
00200 row = false;
00201 cache_rc_valid = false;
00202 }
00203
00204 while (m_nmap.size())
00205 {
00206 std::map<std::string,int>::iterator it = m_nmap.begin();
00207 m_nmap.erase(it);
00208 }
00209 }
00210
00211
00212 bool Query::fetch_row()
00213 {
00214 rowcount = 0;
00215 row = false;
00216 if (odb && res)
00217 {
00218 int rc = cache_rc_valid ? cache_rc : sqlite3_step(res);
00219 cache_rc_valid = false;
00220 switch (rc)
00221 {
00222 case SQLITE_BUSY:
00223 GetDatabase().error(*this, "execute: database busy");
00224 return false;
00225 case SQLITE_DONE:
00226 return false;
00227 case SQLITE_ROW:
00228 row = true;
00229 return true;
00230 case SQLITE_ERROR:
00231 GetDatabase().error(*this, sqlite3_errmsg(odb -> db));
00232 return false;
00233 case SQLITE_MISUSE:
00234 GetDatabase().error(*this, "execute: database misuse");
00235 return false;
00236 }
00237 GetDatabase().error(*this, "execute: unknown result code");
00238 }
00239 return false;
00240 }
00241
00242
00243 sqlite_int64 Query::insert_id()
00244 {
00245 if (odb)
00246 {
00247 return sqlite3_last_insert_rowid(odb -> db);
00248 }
00249 else
00250 {
00251 return 0;
00252 }
00253 }
00254
00255
00256 long Query::num_rows()
00257 {
00258 return odb && res ? m_row_count : 0;
00259 }
00260
00261
00262 int Query::num_cols()
00263 {
00264 return m_num_cols;
00265 }
00266
00267
00268 bool Query::is_null(int x)
00269 {
00270 if (odb && res && row)
00271 {
00272 if (sqlite3_column_type(res, x) == SQLITE_NULL)
00273 return true;
00274 }
00275 return false;
00276 }
00277
00278
00279 const char *Query::getstr(const std::string& x)
00280 {
00281 int index = m_nmap[x] - 1;
00282 if (index >= 0)
00283 return getstr(index);
00284 error("Column name lookup failure: " + x);
00285 return "";
00286 }
00287
00288
00289 const char *Query::getstr(int x)
00290 {
00291 if (odb && res && row && x < sqlite3_column_count(res) )
00292 {
00293 const unsigned char *tmp = sqlite3_column_text(res, x);
00294 return tmp ? (const char *)tmp : "";
00295 }
00296 return "";
00297 }
00298
00299
00300 const char *Query::getstr()
00301 {
00302 return getstr(rowcount++);
00303 }
00304
00305
00306 double Query::getnum(const std::string& x)
00307 {
00308 int index = m_nmap[x] - 1;
00309 if (index >= 0)
00310 return getnum(index);
00311 error("Column name lookup failure: " + x);
00312 return 0;
00313 }
00314
00315
00316 double Query::getnum(int x)
00317 {
00318 if (odb && res && row)
00319 {
00320 return sqlite3_column_double(res, x);
00321 }
00322 return 0;
00323 }
00324
00325
00326 long Query::getval(const std::string& x)
00327 {
00328 int index = m_nmap[x] - 1;
00329 if (index >= 0)
00330 return getval(index);
00331 error("Column name lookup failure: " + x);
00332 return 0;
00333 }
00334
00335
00336 long Query::getval(int x)
00337 {
00338 if (odb && res && row)
00339 {
00340 return sqlite3_column_int(res, x);
00341 }
00342 return 0;
00343 }
00344
00345
00346 double Query::getnum()
00347 {
00348 return getnum(rowcount++);
00349 }
00350
00351
00352 long Query::getval()
00353 {
00354 return getval(rowcount++);
00355 }
00356
00357
00358 unsigned long Query::getuval(const std::string& x)
00359 {
00360 int index = m_nmap[x] - 1;
00361 if (index >= 0)
00362 return getuval(index);
00363 error("Column name lookup failure: " + x);
00364 return 0;
00365 }
00366
00367
00368 unsigned long Query::getuval(int x)
00369 {
00370 unsigned long l = 0;
00371 if (odb && res && row)
00372 {
00373 l = sqlite3_column_int(res, x);
00374 }
00375 return l;
00376 }
00377
00378
00379 unsigned long Query::getuval()
00380 {
00381 return getuval(rowcount++);
00382 }
00383
00384
00385 int64_t Query::getbigint(const std::string& x)
00386 {
00387 int index = m_nmap[x] - 1;
00388 if (index >= 0)
00389 return getbigint(index);
00390 error("Column name lookup failure: " + x);
00391 return 0;
00392 }
00393
00394
00395 int64_t Query::getbigint(int x)
00396 {
00397 if (odb && res && row)
00398 {
00399 return sqlite3_column_int64(res, x);
00400 }
00401 return 0;
00402 }
00403
00404
00405 int64_t Query::getbigint()
00406 {
00407 return getbigint(rowcount++);
00408 }
00409
00410
00411 uint64_t Query::getubigint(const std::string& x)
00412 {
00413 int index = m_nmap[x] - 1;
00414 if (index >= 0)
00415 return getubigint(index);
00416 error("Column name lookup failure: " + x);
00417 return 0;
00418 }
00419
00420
00421 uint64_t Query::getubigint(int x)
00422 {
00423 uint64_t l = 0;
00424 if (odb && res && row)
00425 {
00426 l = sqlite3_column_int64(res, x);
00427 }
00428 return l;
00429 }
00430
00431
00432 uint64_t Query::getubigint()
00433 {
00434 return getubigint(rowcount++);
00435 }
00436
00437
00438 double Query::get_num(const std::string& sql)
00439 {
00440 double l = 0;
00441 if (get_result(sql))
00442 {
00443 if (fetch_row())
00444 {
00445 l = getnum();
00446 }
00447 free_result();
00448 }
00449 return l;
00450 }
00451
00452
00453 long Query::get_count(const std::string& sql)
00454 {
00455 long l = 0;
00456 if (get_result(sql))
00457 {
00458 if (fetch_row())
00459 l = getval();
00460 free_result();
00461 }
00462 return l;
00463 }
00464
00465
00466 const char *Query::get_string(const std::string& sql)
00467 {
00468 bool found = false;
00469 m_tmpstr = "";
00470 if (get_result(sql))
00471 {
00472 if (fetch_row())
00473 {
00474 m_tmpstr = getstr();
00475 found = true;
00476 }
00477 free_result();
00478 }
00479 return m_tmpstr.c_str();
00480 }
00481
00482
00483 const std::string& Query::GetLastQuery()
00484 {
00485 return m_last_query;
00486 }
00487
00488
00489 std::string Query::GetError()
00490 {
00491 if (odb)
00492 return sqlite3_errmsg(odb -> db);
00493 return "";
00494 }
00495
00496
00497 int Query::GetErrno()
00498 {
00499 if (odb)
00500 return sqlite3_errcode(odb -> db);
00501 return 0;
00502 }
00503
00504
00505 bool Query::Connected()
00506 {
00507 return odb ? true : false;
00508 }
00509
00510
00511
00512
00513 void Query::ViewRes()
00514 {
00515 if (!res)
00516 {
00517 printf("no result stored\n");
00518 return;
00519 }
00520 printf("result column count = %d\n", sqlite3_column_count(res));
00521 for (int i = 0; i < sqlite3_column_count(res); i++)
00522 {
00523 printf(" %2d type %d name '%s'", i, sqlite3_column_type(res, i), sqlite3_column_name(res, i));
00524 printf(" / '%s'", (char *)sqlite3_column_text(res, i));
00525 printf(" / %d", sqlite3_column_int(res, i));
00526 printf(" / %f", sqlite3_column_double(res, i));
00527 printf("\n");
00528 }
00529 }
00530
00531
00532 void Query::error(const std::string& msg)
00533 {
00534 GetDatabase().error(*this, msg);
00535 }
00536
00537
00538 #ifdef SQLITEW_NAMESPACE
00539 }
00540 #endif
00541