extensions/sqlite/driver/SqDatabase.cpp
author David Anderson <dvander@alliedmods.net>
Wed Aug 01 01:54:53 2007 +0000 (2007-08-01)
changeset 1226 478550a4d5ec
parent 1203 633c25ce6405
child 1330 ab94316bb52b
permissions -rw-r--r--
updated license headers for most extensions
updated sdk bases for most extensions
dvander@1203
     1
/**
dvander@1203
     2
 * vim: set ts=4 :
dvander@1226
     3
 * ================================================================
dvander@1226
     4
 * SourceMod SQLite Extension
dvander@1226
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
dvander@1226
     6
 * ================================================================
dvander@1203
     7
 *
dvander@1226
     8
 * This program is free software; you can redistribute it and/or 
dvander@1226
     9
 * modify it under the terms of the GNU General Public License, 
dvander@1226
    10
 * version 3.0, as published by the Free Software Foundation.
dvander@1226
    11
 * 
dvander@1203
    12
 * This program is distributed in the hope that it will be useful,
dvander@1203
    13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
dvander@1203
    14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dvander@1203
    15
 * GNU General Public License for more details.
dvander@1226
    16
 *
dvander@1203
    17
 * You should have received a copy of the GNU General Public License
dvander@1226
    18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1226
    19
 *
dvander@1226
    20
 * As a special exception, AlliedModders LLC gives you permission to 
dvander@1226
    21
 * link the code of this program (as well as its derivative works) to 
dvander@1226
    22
 * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any 
dvander@1226
    23
 * Game MODs that run on software by the Valve Corporation.  You must 
dvander@1226
    24
 * obey the GNU General Public License in all respects for all other 
dvander@1226
    25
 * code used. Additionally, AlliedModders LLC grants this exception 
dvander@1226
    26
 * to all derivative works. AlliedModders LLC defines further 
dvander@1226
    27
 * exceptions, found in LICENSE.txt (as of this writing, version 
dvander@1226
    28
 * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
dvander@1203
    29
 *
dvander@1203
    30
 * Version: $Id$
dvander@1203
    31
 */
dvander@1203
    32
dvander@1203
    33
#include "extension.h"
dvander@1203
    34
#include "SqDatabase.h"
dvander@1203
    35
#include "SqQuery.h"
dvander@1203
    36
dvander@1203
    37
SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) : 
dvander@1203
    38
	m_sq3(sq3), m_refcount(1), m_pFullLock(NULL), m_Persistent(persistent)
dvander@1203
    39
{
dvander@1203
    40
	m_pRefLock = threader->MakeMutex();
dvander@1203
    41
}
dvander@1203
    42
dvander@1203
    43
SqDatabase::~SqDatabase()
dvander@1203
    44
{
dvander@1203
    45
	m_pRefLock->DestroyThis();
dvander@1203
    46
	if (m_pFullLock)
dvander@1203
    47
	{
dvander@1203
    48
		m_pFullLock->DestroyThis();
dvander@1203
    49
	}
dvander@1203
    50
	sqlite3_close(m_sq3);
dvander@1203
    51
}
dvander@1203
    52
dvander@1203
    53
void SqDatabase::IncReferenceCount()
dvander@1203
    54
{
dvander@1203
    55
	m_pRefLock->Lock();
dvander@1203
    56
	m_refcount++;
dvander@1203
    57
	m_pRefLock->Unlock();
dvander@1203
    58
}
dvander@1203
    59
dvander@1203
    60
bool SqDatabase::Close()
dvander@1203
    61
{
dvander@1203
    62
	m_pRefLock->Lock();
dvander@1203
    63
	if (m_refcount > 1)
dvander@1203
    64
	{
dvander@1203
    65
		m_refcount--;
dvander@1203
    66
		m_pRefLock->Unlock();
dvander@1203
    67
		return false;
dvander@1203
    68
	}
dvander@1203
    69
	m_pRefLock->Unlock();
dvander@1203
    70
dvander@1203
    71
	if (m_Persistent)
dvander@1203
    72
	{
dvander@1203
    73
		g_SqDriver.RemovePersistent(this);
dvander@1203
    74
	}
dvander@1203
    75
dvander@1203
    76
	delete this;
dvander@1203
    77
dvander@1203
    78
	return true;
dvander@1203
    79
}
dvander@1203
    80
dvander@1203
    81
const char *SqDatabase::GetError(int *errorCode/* =NULL */)
dvander@1203
    82
{
dvander@1203
    83
	return sqlite3_errmsg(m_sq3);
dvander@1203
    84
}
dvander@1203
    85
dvander@1203
    86
bool SqDatabase::LockForFullAtomicOperation()
dvander@1203
    87
{
dvander@1203
    88
	if (!m_pFullLock)
dvander@1203
    89
	{
dvander@1203
    90
		m_pFullLock = threader->MakeMutex();
dvander@1203
    91
		if (!m_pFullLock)
dvander@1203
    92
		{
dvander@1203
    93
			return false;
dvander@1203
    94
		}
dvander@1203
    95
	}
dvander@1203
    96
dvander@1203
    97
	m_pFullLock->Lock();
dvander@1203
    98
dvander@1203
    99
	return true;
dvander@1203
   100
}
dvander@1203
   101
dvander@1203
   102
void SqDatabase::UnlockFromFullAtomicOperation()
dvander@1203
   103
{
dvander@1203
   104
	if (m_pFullLock)
dvander@1203
   105
	{
dvander@1203
   106
		m_pFullLock->Unlock();
dvander@1203
   107
	}
dvander@1203
   108
}
dvander@1203
   109
dvander@1203
   110
IDBDriver *SqDatabase::GetDriver()
dvander@1203
   111
{
dvander@1203
   112
	return &g_SqDriver;
dvander@1203
   113
}
dvander@1203
   114
dvander@1203
   115
bool SqDatabase::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize)
dvander@1203
   116
{
dvander@1203
   117
	char *res = sqlite3_snprintf(static_cast<int>(maxlen), buffer, "%q", str);
dvander@1203
   118
dvander@1203
   119
	if (res != NULL && newSize != NULL)
dvander@1203
   120
	{
dvander@1203
   121
		*newSize = strlen(buffer);
dvander@1203
   122
	}
dvander@1203
   123
dvander@1203
   124
	return (res != NULL);
dvander@1203
   125
}
dvander@1203
   126
dvander@1203
   127
unsigned int SqDatabase::GetInsertID()
dvander@1203
   128
{
dvander@1203
   129
	return (unsigned int)sqlite3_last_insert_rowid(m_sq3);
dvander@1203
   130
}
dvander@1203
   131
dvander@1203
   132
unsigned int SqDatabase::GetAffectedRows()
dvander@1203
   133
{
dvander@1203
   134
	return (unsigned int)sqlite3_changes(m_sq3);
dvander@1203
   135
}
dvander@1203
   136
dvander@1203
   137
bool SqDatabase::DoSimpleQuery(const char *query)
dvander@1203
   138
{
dvander@1203
   139
	IQuery *pQuery = DoQuery(query);
dvander@1203
   140
	if (!pQuery)
dvander@1203
   141
	{
dvander@1203
   142
		return false;
dvander@1203
   143
	}
dvander@1203
   144
	pQuery->Destroy();
dvander@1203
   145
	return true;
dvander@1203
   146
}
dvander@1203
   147
dvander@1203
   148
/* this sounds like daiquiri.. i'm tired. */
dvander@1203
   149
IQuery *SqDatabase::DoQuery(const char *query)
dvander@1203
   150
{
dvander@1203
   151
	IPreparedQuery *pQuery = PrepareQuery(query, NULL, 0, NULL);
dvander@1203
   152
	if (!pQuery)
dvander@1203
   153
	{
dvander@1203
   154
		return NULL;
dvander@1203
   155
	}
dvander@1203
   156
	if (!pQuery->Execute())
dvander@1203
   157
	{
dvander@1203
   158
		pQuery->Destroy();
dvander@1203
   159
		return NULL;
dvander@1203
   160
	}
dvander@1203
   161
	return pQuery;
dvander@1203
   162
}
dvander@1203
   163
dvander@1203
   164
IPreparedQuery *SqDatabase::PrepareQuery(const char *query, char *error, size_t maxlength, int *errCode/* =NULL */)
dvander@1203
   165
{
dvander@1203
   166
	sqlite3_stmt *stmt = NULL;
dvander@1203
   167
	if ((m_LastErrorCode = sqlite3_prepare_v2(m_sq3, query, -1, &stmt, NULL)) != SQLITE_OK
dvander@1203
   168
		|| !stmt)
dvander@1203
   169
	{
dvander@1203
   170
		const char *msg;
dvander@1203
   171
		if (m_LastErrorCode != SQLITE_OK)
dvander@1203
   172
		{
dvander@1203
   173
			msg = sqlite3_errmsg(m_sq3);
dvander@1203
   174
		} else {
dvander@1203
   175
			msg = "Invalid query string";
dvander@1203
   176
			m_LastErrorCode = SQLITE_MISUSE;
dvander@1203
   177
		}
dvander@1203
   178
		if (error)
dvander@1203
   179
		{
dvander@1203
   180
			strncopy(error, msg, maxlength);
dvander@1203
   181
		}
dvander@1203
   182
		m_LastError.assign(msg);
dvander@1203
   183
		if (stmt)
dvander@1203
   184
		{
dvander@1203
   185
			sqlite3_finalize(stmt);
dvander@1203
   186
		}
dvander@1203
   187
		return NULL;
dvander@1203
   188
	}
dvander@1203
   189
	return new SqQuery(this, stmt);
dvander@1203
   190
}
dvander@1203
   191
dvander@1203
   192
sqlite3 *SqDatabase::GetDb()
dvander@1203
   193
{
dvander@1203
   194
	return m_sq3;
dvander@1203
   195
}