187 lines
3.8 KiB
C++
187 lines
3.8 KiB
C++
|
/**
|
||
|
* vim: set ts=4 :
|
||
|
* ===============================================================
|
||
|
* SourceMod SQLite Driver Extension
|
||
|
* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
|
||
|
* ===============================================================
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
* Version: $Id$
|
||
|
*/
|
||
|
|
||
|
#include "extension.h"
|
||
|
#include "SqDatabase.h"
|
||
|
#include "SqQuery.h"
|
||
|
|
||
|
SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) :
|
||
|
m_sq3(sq3), m_refcount(1), m_pFullLock(NULL), m_Persistent(persistent)
|
||
|
{
|
||
|
m_pRefLock = threader->MakeMutex();
|
||
|
}
|
||
|
|
||
|
SqDatabase::~SqDatabase()
|
||
|
{
|
||
|
m_pRefLock->DestroyThis();
|
||
|
if (m_pFullLock)
|
||
|
{
|
||
|
m_pFullLock->DestroyThis();
|
||
|
}
|
||
|
sqlite3_close(m_sq3);
|
||
|
}
|
||
|
|
||
|
void SqDatabase::IncReferenceCount()
|
||
|
{
|
||
|
m_pRefLock->Lock();
|
||
|
m_refcount++;
|
||
|
m_pRefLock->Unlock();
|
||
|
}
|
||
|
|
||
|
bool SqDatabase::Close()
|
||
|
{
|
||
|
m_pRefLock->Lock();
|
||
|
if (m_refcount > 1)
|
||
|
{
|
||
|
m_refcount--;
|
||
|
m_pRefLock->Unlock();
|
||
|
return false;
|
||
|
}
|
||
|
m_pRefLock->Unlock();
|
||
|
|
||
|
if (m_Persistent)
|
||
|
{
|
||
|
g_SqDriver.RemovePersistent(this);
|
||
|
}
|
||
|
|
||
|
delete this;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
const char *SqDatabase::GetError(int *errorCode/* =NULL */)
|
||
|
{
|
||
|
return sqlite3_errmsg(m_sq3);
|
||
|
}
|
||
|
|
||
|
bool SqDatabase::LockForFullAtomicOperation()
|
||
|
{
|
||
|
if (!m_pFullLock)
|
||
|
{
|
||
|
m_pFullLock = threader->MakeMutex();
|
||
|
if (!m_pFullLock)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_pFullLock->Lock();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void SqDatabase::UnlockFromFullAtomicOperation()
|
||
|
{
|
||
|
if (m_pFullLock)
|
||
|
{
|
||
|
m_pFullLock->Unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IDBDriver *SqDatabase::GetDriver()
|
||
|
{
|
||
|
return &g_SqDriver;
|
||
|
}
|
||
|
|
||
|
bool SqDatabase::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize)
|
||
|
{
|
||
|
char *res = sqlite3_snprintf(static_cast<int>(maxlen), buffer, "%q", str);
|
||
|
|
||
|
if (res != NULL && newSize != NULL)
|
||
|
{
|
||
|
*newSize = strlen(buffer);
|
||
|
}
|
||
|
|
||
|
return (res != NULL);
|
||
|
}
|
||
|
|
||
|
unsigned int SqDatabase::GetInsertID()
|
||
|
{
|
||
|
return (unsigned int)sqlite3_last_insert_rowid(m_sq3);
|
||
|
}
|
||
|
|
||
|
unsigned int SqDatabase::GetAffectedRows()
|
||
|
{
|
||
|
return (unsigned int)sqlite3_changes(m_sq3);
|
||
|
}
|
||
|
|
||
|
bool SqDatabase::DoSimpleQuery(const char *query)
|
||
|
{
|
||
|
IQuery *pQuery = DoQuery(query);
|
||
|
if (!pQuery)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
pQuery->Destroy();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/* this sounds like daiquiri.. i'm tired. */
|
||
|
IQuery *SqDatabase::DoQuery(const char *query)
|
||
|
{
|
||
|
IPreparedQuery *pQuery = PrepareQuery(query, NULL, 0, NULL);
|
||
|
if (!pQuery)
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
if (!pQuery->Execute())
|
||
|
{
|
||
|
pQuery->Destroy();
|
||
|
return NULL;
|
||
|
}
|
||
|
return pQuery;
|
||
|
}
|
||
|
|
||
|
IPreparedQuery *SqDatabase::PrepareQuery(const char *query, char *error, size_t maxlength, int *errCode/* =NULL */)
|
||
|
{
|
||
|
sqlite3_stmt *stmt = NULL;
|
||
|
if ((m_LastErrorCode = sqlite3_prepare_v2(m_sq3, query, -1, &stmt, NULL)) != SQLITE_OK
|
||
|
|| !stmt)
|
||
|
{
|
||
|
const char *msg;
|
||
|
if (m_LastErrorCode != SQLITE_OK)
|
||
|
{
|
||
|
msg = sqlite3_errmsg(m_sq3);
|
||
|
} else {
|
||
|
msg = "Invalid query string";
|
||
|
m_LastErrorCode = SQLITE_MISUSE;
|
||
|
}
|
||
|
if (error)
|
||
|
{
|
||
|
strncopy(error, msg, maxlength);
|
||
|
}
|
||
|
m_LastError.assign(msg);
|
||
|
if (stmt)
|
||
|
{
|
||
|
sqlite3_finalize(stmt);
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
return new SqQuery(this, stmt);
|
||
|
}
|
||
|
|
||
|
sqlite3 *SqDatabase::GetDb()
|
||
|
{
|
||
|
return m_sq3;
|
||
|
}
|