1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/extensions/sqlite/driver/SqDatabase.cpp Sun Jul 29 01:15:31 2007 +0000
1.3 @@ -0,0 +1,186 @@
1.4 +/**
1.5 + * vim: set ts=4 :
1.6 + * ===============================================================
1.7 + * SourceMod SQLite Driver Extension
1.8 + * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
1.9 + * ===============================================================
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or
1.12 + * modify it under the terms of the GNU General Public License
1.13 + * as published by the Free Software Foundation; either version 2
1.14 + * of the License, or (at your option) any later version.
1.15 + * This program is distributed in the hope that it will be useful,
1.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.18 + * GNU General Public License for more details.
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License
1.21 + * along with this program; if not, write to the Free Software
1.22 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1.23 + *
1.24 + * Version: $Id$
1.25 + */
1.26 +
1.27 +#include "extension.h"
1.28 +#include "SqDatabase.h"
1.29 +#include "SqQuery.h"
1.30 +
1.31 +SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) :
1.32 + m_sq3(sq3), m_refcount(1), m_pFullLock(NULL), m_Persistent(persistent)
1.33 +{
1.34 + m_pRefLock = threader->MakeMutex();
1.35 +}
1.36 +
1.37 +SqDatabase::~SqDatabase()
1.38 +{
1.39 + m_pRefLock->DestroyThis();
1.40 + if (m_pFullLock)
1.41 + {
1.42 + m_pFullLock->DestroyThis();
1.43 + }
1.44 + sqlite3_close(m_sq3);
1.45 +}
1.46 +
1.47 +void SqDatabase::IncReferenceCount()
1.48 +{
1.49 + m_pRefLock->Lock();
1.50 + m_refcount++;
1.51 + m_pRefLock->Unlock();
1.52 +}
1.53 +
1.54 +bool SqDatabase::Close()
1.55 +{
1.56 + m_pRefLock->Lock();
1.57 + if (m_refcount > 1)
1.58 + {
1.59 + m_refcount--;
1.60 + m_pRefLock->Unlock();
1.61 + return false;
1.62 + }
1.63 + m_pRefLock->Unlock();
1.64 +
1.65 + if (m_Persistent)
1.66 + {
1.67 + g_SqDriver.RemovePersistent(this);
1.68 + }
1.69 +
1.70 + delete this;
1.71 +
1.72 + return true;
1.73 +}
1.74 +
1.75 +const char *SqDatabase::GetError(int *errorCode/* =NULL */)
1.76 +{
1.77 + return sqlite3_errmsg(m_sq3);
1.78 +}
1.79 +
1.80 +bool SqDatabase::LockForFullAtomicOperation()
1.81 +{
1.82 + if (!m_pFullLock)
1.83 + {
1.84 + m_pFullLock = threader->MakeMutex();
1.85 + if (!m_pFullLock)
1.86 + {
1.87 + return false;
1.88 + }
1.89 + }
1.90 +
1.91 + m_pFullLock->Lock();
1.92 +
1.93 + return true;
1.94 +}
1.95 +
1.96 +void SqDatabase::UnlockFromFullAtomicOperation()
1.97 +{
1.98 + if (m_pFullLock)
1.99 + {
1.100 + m_pFullLock->Unlock();
1.101 + }
1.102 +}
1.103 +
1.104 +IDBDriver *SqDatabase::GetDriver()
1.105 +{
1.106 + return &g_SqDriver;
1.107 +}
1.108 +
1.109 +bool SqDatabase::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize)
1.110 +{
1.111 + char *res = sqlite3_snprintf(static_cast<int>(maxlen), buffer, "%q", str);
1.112 +
1.113 + if (res != NULL && newSize != NULL)
1.114 + {
1.115 + *newSize = strlen(buffer);
1.116 + }
1.117 +
1.118 + return (res != NULL);
1.119 +}
1.120 +
1.121 +unsigned int SqDatabase::GetInsertID()
1.122 +{
1.123 + return (unsigned int)sqlite3_last_insert_rowid(m_sq3);
1.124 +}
1.125 +
1.126 +unsigned int SqDatabase::GetAffectedRows()
1.127 +{
1.128 + return (unsigned int)sqlite3_changes(m_sq3);
1.129 +}
1.130 +
1.131 +bool SqDatabase::DoSimpleQuery(const char *query)
1.132 +{
1.133 + IQuery *pQuery = DoQuery(query);
1.134 + if (!pQuery)
1.135 + {
1.136 + return false;
1.137 + }
1.138 + pQuery->Destroy();
1.139 + return true;
1.140 +}
1.141 +
1.142 +/* this sounds like daiquiri.. i'm tired. */
1.143 +IQuery *SqDatabase::DoQuery(const char *query)
1.144 +{
1.145 + IPreparedQuery *pQuery = PrepareQuery(query, NULL, 0, NULL);
1.146 + if (!pQuery)
1.147 + {
1.148 + return NULL;
1.149 + }
1.150 + if (!pQuery->Execute())
1.151 + {
1.152 + pQuery->Destroy();
1.153 + return NULL;
1.154 + }
1.155 + return pQuery;
1.156 +}
1.157 +
1.158 +IPreparedQuery *SqDatabase::PrepareQuery(const char *query, char *error, size_t maxlength, int *errCode/* =NULL */)
1.159 +{
1.160 + sqlite3_stmt *stmt = NULL;
1.161 + if ((m_LastErrorCode = sqlite3_prepare_v2(m_sq3, query, -1, &stmt, NULL)) != SQLITE_OK
1.162 + || !stmt)
1.163 + {
1.164 + const char *msg;
1.165 + if (m_LastErrorCode != SQLITE_OK)
1.166 + {
1.167 + msg = sqlite3_errmsg(m_sq3);
1.168 + } else {
1.169 + msg = "Invalid query string";
1.170 + m_LastErrorCode = SQLITE_MISUSE;
1.171 + }
1.172 + if (error)
1.173 + {
1.174 + strncopy(error, msg, maxlength);
1.175 + }
1.176 + m_LastError.assign(msg);
1.177 + if (stmt)
1.178 + {
1.179 + sqlite3_finalize(stmt);
1.180 + }
1.181 + return NULL;
1.182 + }
1.183 + return new SqQuery(this, stmt);
1.184 +}
1.185 +
1.186 +sqlite3 *SqDatabase::GetDb()
1.187 +{
1.188 + return m_sq3;
1.189 +}