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 #include <stdio.h>
00033 #ifdef _WIN32
00034 #pragma warning(disable:4786)
00035 #endif
00036
00037 #include <string>
00038 #include <map>
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <sqlite3.h>
00043 #include <stdarg.h>
00044
00045 #include "IError.h"
00046 #include "Database.h"
00047
00048
00049 #ifdef SQLITEW_NAMESPACE
00050 namespace SQLITEW_NAMESPACE {
00051 #endif
00052
00053
00054 Database::Database(const std::string& d,IError *e)
00055 :database(d)
00056 ,m_errhandler(e)
00057 ,m_embedded(true)
00058 ,m_mutex(m_mutex)
00059 ,m_b_use_mutex(false)
00060 {
00061 }
00062
00063
00064 Database::Database(Mutex& m,const std::string& d,IError *e)
00065 :database(d)
00066 ,m_errhandler(e)
00067 ,m_embedded(true)
00068 ,m_mutex(m)
00069 ,m_b_use_mutex(true)
00070 {
00071 }
00072
00073
00074 Database::~Database()
00075 {
00076 for (opendb_v::iterator it = m_opendbs.begin(); it != m_opendbs.end(); it++)
00077 {
00078 OPENDB *p = *it;
00079 sqlite3_close(p -> db);
00080 }
00081 while (m_opendbs.size())
00082 {
00083 opendb_v::iterator it = m_opendbs.begin();
00084 OPENDB *p = *it;
00085 if (p -> busy)
00086 {
00087 error("destroying Database object before Query object");
00088 }
00089 delete p;
00090 m_opendbs.erase(it);
00091 }
00092 }
00093
00094
00095 void Database::RegErrHandler(IError *p)
00096 {
00097 m_errhandler = p;
00098 }
00099
00100
00101 Database::OPENDB *Database::grabdb()
00102 {
00103 Lock lck(m_mutex, m_b_use_mutex);
00104 OPENDB *odb = NULL;
00105
00106 for (opendb_v::iterator it = m_opendbs.begin(); it != m_opendbs.end(); it++)
00107 {
00108 odb = *it;
00109 if (!odb -> busy)
00110 {
00111 break;
00112 }
00113 else
00114 {
00115 odb = NULL;
00116 }
00117 }
00118 if (!odb)
00119 {
00120 odb = new OPENDB;
00121 if (!odb)
00122 {
00123 error("grabdb: OPENDB struct couldn't be created");
00124 return NULL;
00125 }
00126 int rc = sqlite3_open(database.c_str(), &odb -> db);
00127 if (rc)
00128 {
00129 error("Can't open database: %s\n", sqlite3_errmsg(odb -> db));
00130 sqlite3_close(odb -> db);
00131 delete odb;
00132 return NULL;
00133 }
00134 odb -> busy = true;
00135 m_opendbs.push_back(odb);
00136 }
00137 else
00138 {
00139 odb -> busy = true;
00140 }
00141 return odb;
00142 }
00143
00144
00145 void Database::freedb(Database::OPENDB *odb)
00146 {
00147 Lock lck(m_mutex, m_b_use_mutex);
00148 if (odb)
00149 {
00150 odb -> busy = false;
00151 }
00152 }
00153
00154
00155 void Database::error(const char *format, ...)
00156 {
00157 if (m_errhandler)
00158 {
00159 va_list ap;
00160 char errstr[5000];
00161 va_start(ap, format);
00162 #ifdef WIN32
00163 vsprintf(errstr, format, ap);
00164 #else
00165 vsnprintf(errstr, 5000, format, ap);
00166 #endif
00167 va_end(ap);
00168 m_errhandler -> error(*this, errstr);
00169 }
00170 }
00171
00172
00173 void Database::error(Query& q,const char *format, ...)
00174 {
00175 if (m_errhandler)
00176 {
00177 va_list ap;
00178 char errstr[5000];
00179 va_start(ap, format);
00180 #ifdef WIN32
00181 vsprintf(errstr, format, ap);
00182 #else
00183 vsnprintf(errstr, 5000, format, ap);
00184 #endif
00185 va_end(ap);
00186 m_errhandler -> error(*this, q, errstr);
00187 }
00188 }
00189
00190
00191 void Database::error(Query& q,const std::string& msg)
00192 {
00193 if (m_errhandler)
00194 {
00195 m_errhandler -> error(*this, q, msg);
00196 }
00197 }
00198
00199
00200 bool Database::Connected()
00201 {
00202 OPENDB *odb = grabdb();
00203 if (!odb)
00204 {
00205 return false;
00206 }
00207 freedb(odb);
00208 return true;
00209 }
00210
00211
00212 Database::Lock::Lock(Mutex& mutex,bool use) : m_mutex(mutex),m_b_use(use)
00213 {
00214 if (m_b_use)
00215 {
00216 m_mutex.Lock();
00217 }
00218 }
00219
00220
00221 Database::Lock::~Lock()
00222 {
00223 if (m_b_use)
00224 {
00225 m_mutex.Unlock();
00226 }
00227 }
00228
00229
00230 Database::Mutex::Mutex()
00231 {
00232 #ifdef _WIN32
00233 m_mutex = ::CreateMutex(NULL, FALSE, NULL);
00234 #else
00235 pthread_mutex_init(&m_mutex, NULL);
00236 #endif
00237 }
00238
00239
00240 Database::Mutex::~Mutex()
00241 {
00242 #ifdef _WIN32
00243 ::CloseHandle(m_mutex);
00244 #else
00245 pthread_mutex_destroy(&m_mutex);
00246 #endif
00247 }
00248
00249
00250 void Database::Mutex::Lock()
00251 {
00252 #ifdef _WIN32
00253 DWORD d = WaitForSingleObject(m_mutex, INFINITE);
00254
00255 #else
00256 pthread_mutex_lock(&m_mutex);
00257 #endif
00258 }
00259
00260
00261 void Database::Mutex::Unlock()
00262 {
00263 #ifdef _WIN32
00264 ::ReleaseMutex(m_mutex);
00265 #else
00266 pthread_mutex_unlock(&m_mutex);
00267 #endif
00268 }
00269
00270
00271 std::string Database::safestr(const std::string& str)
00272 {
00273 std::string str2;
00274 for (size_t i = 0; i < str.size(); i++)
00275 {
00276 switch (str[i])
00277 {
00278 case '\'':
00279 case '\\':
00280 case 34:
00281 str2 += '\'';
00282 default:
00283 str2 += str[i];
00284 }
00285 }
00286 return str2;
00287 }
00288
00289
00290 std::string Database::xmlsafestr(const std::string& str)
00291 {
00292 std::string str2;
00293 for (size_t i = 0; i < str.size(); i++)
00294 {
00295 switch (str[i])
00296 {
00297 case '&':
00298 str2 += "&";
00299 break;
00300 case '<':
00301 str2 += "<";
00302 break;
00303 case '>':
00304 str2 += ">";
00305 break;
00306 case '"':
00307 str2 += """;
00308 break;
00309 case '\'':
00310 str2 += "'";
00311 break;
00312 default:
00313 str2 += str[i];
00314 }
00315 }
00316 return str2;
00317 }
00318
00319
00320 int64_t Database::a2bigint(const std::string& str)
00321 {
00322 int64_t val = 0;
00323 bool sign = false;
00324 size_t i = 0;
00325 if (str[i] == '-')
00326 {
00327 sign = true;
00328 i++;
00329 }
00330 for (; i < str.size(); i++)
00331 {
00332 val = val * 10 + (str[i] - 48);
00333 }
00334 return sign ? -val : val;
00335 }
00336
00337
00338 uint64_t Database::a2ubigint(const std::string& str)
00339 {
00340 uint64_t val = 0;
00341 for (size_t i = 0; i < str.size(); i++)
00342 {
00343 val = val * 10 + (str[i] - 48);
00344 }
00345 return val;
00346 }
00347
00348
00349 #ifdef SQLITEW_NAMESPACE
00350 }
00351 #endif
00352