Make SQL_LastInsertId and SQL_GetAffectedRows work on query handles, allowing their use with threaded queries
3 * =============================================================================
4 * SourceMod SQLite Extension
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "extension.h"
33 #include "SqDatabase.h"
36 SqDatabase::SqDatabase(sqlite3 *sq3, bool persistent) :
37 m_sq3(sq3), m_refcount(1), m_pFullLock(NULL), m_Persistent(persistent)
39 m_pRefLock = threader->MakeMutex();
42 SqDatabase::~SqDatabase()
44 m_pRefLock->DestroyThis();
47 m_pFullLock->DestroyThis();
52 void SqDatabase::IncReferenceCount()
59 bool SqDatabase::Close()
72 g_SqDriver.RemovePersistent(this);
80 const char *SqDatabase::GetError(int *errorCode/* =NULL */)
82 return sqlite3_errmsg(m_sq3);
85 bool SqDatabase::LockForFullAtomicOperation()
89 m_pFullLock = threader->MakeMutex();
101 void SqDatabase::UnlockFromFullAtomicOperation()
105 m_pFullLock->Unlock();
109 IDBDriver *SqDatabase::GetDriver()
114 bool SqDatabase::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newSize)
116 char *res = sqlite3_snprintf(static_cast<int>(maxlen), buffer, "%q", str);
118 if (res != NULL && newSize != NULL)
120 *newSize = strlen(buffer);
123 return (res != NULL);
126 unsigned int SqDatabase::GetInsertID()
128 return (unsigned int)sqlite3_last_insert_rowid(m_sq3);
131 unsigned int SqDatabase::GetAffectedRows()
133 return (unsigned int)sqlite3_changes(m_sq3);
136 bool SqDatabase::DoSimpleQuery(const char *query)
138 IQuery *pQuery = DoQuery(query);
147 /* this sounds like daiquiri.. i'm tired. */
148 IQuery *SqDatabase::DoQuery(const char *query)
150 IPreparedQuery *pQuery = PrepareQuery(query, NULL, 0, NULL);
155 if (!pQuery->Execute())
163 bool SqDatabase::DoSimpleQueryEx(const char *query, size_t len)
165 IQuery *pQuery = DoQueryEx(query, len);
174 IQuery *SqDatabase::DoQueryEx(const char *query, size_t len)
176 IPreparedQuery *pQuery = PrepareQueryEx(query, len, NULL, 0, NULL);
181 if (!pQuery->Execute())
189 unsigned int SqDatabase::GetAffectedRowsForQuery(IQuery *query)
191 return static_cast<SqQuery*>(query)->GetAffectedRows();
193 unsigned int SqDatabase::GetInsertIDForQuery(IQuery *query)
195 return static_cast<SqQuery*>(query)->GetInsertID();
198 IPreparedQuery *SqDatabase::PrepareQuery(const char *query,
201 int *errCode/* =NULL */)
203 sqlite3_stmt *stmt = NULL;
204 if ((m_LastErrorCode = sqlite3_prepare_v2(m_sq3, query, -1, &stmt, NULL)) != SQLITE_OK
208 if (m_LastErrorCode != SQLITE_OK)
210 msg = sqlite3_errmsg(m_sq3);
212 msg = "Invalid query string";
213 m_LastErrorCode = SQLITE_ERROR;
217 strncopy(error, msg, maxlength);
219 m_LastError.assign(msg);
222 return new SqQuery(this, stmt);
225 IPreparedQuery *SqDatabase::PrepareQueryEx(const char *query,
229 int *errCode/* =NULL */)
231 sqlite3_stmt *stmt = NULL;
232 if ((m_LastErrorCode = sqlite3_prepare_v2(m_sq3, query, len, &stmt, NULL)) != SQLITE_OK
236 if (m_LastErrorCode != SQLITE_OK)
238 msg = sqlite3_errmsg(m_sq3);
240 msg = "Invalid query string";
241 m_LastErrorCode = SQLITE_ERROR;
245 strncopy(error, msg, maxlength);
247 m_LastError.assign(msg);
250 return new SqQuery(this, stmt);
253 sqlite3 *SqDatabase::GetDb()