extensions/sqlite/driver/SqQuery.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Sep 14 03:01:05 2008 -0500 (2008-09-14)
changeset 2289 44045ead61cd
parent 1952 b7aa2b626807
parent 1947 e73a1e51833b
child 4040 b6924c1a1d71
permissions -rw-r--r--
Eliminated head: da55a80522cf, a remnant of sourcemod-1.1.0 branch
dvander@1203
     1
/**
dvander@1203
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1226
     4
 * SourceMod SQLite Extension
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@1203
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1226
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1226
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1226
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@1203
    28
 *
dvander@1203
    29
 * Version: $Id$
dvander@1203
    30
 */
dvander@1203
    31
dvander@1203
    32
#include "SqQuery.h"
dvander@1203
    33
dvander@1203
    34
SqQuery::SqQuery(SqDatabase *parent, sqlite3_stmt *stmt) : 
dvander@1203
    35
 m_pParent(parent), m_pStmt(stmt), m_pResults(NULL), m_AffectedRows(0), m_InsertID(0)
dvander@1203
    36
{
dvander@1203
    37
	m_ParamCount = sqlite3_bind_parameter_count(m_pStmt);
dvander@1210
    38
	m_ColCount = sqlite3_column_count(m_pStmt);
dvander@1203
    39
	m_pParent->IncReferenceCount();
dvander@1203
    40
}
dvander@1203
    41
dvander@1203
    42
SqQuery::~SqQuery()
dvander@1203
    43
{
dvander@1203
    44
	delete m_pResults;
dvander@1203
    45
	sqlite3_finalize(m_pStmt);
dvander@1203
    46
	m_pParent->Close();
dvander@1203
    47
}
dvander@1203
    48
dvander@1203
    49
IResultSet *SqQuery::GetResultSet()
dvander@1203
    50
{
dvander@1203
    51
	return m_pResults;
dvander@1203
    52
}
dvander@1203
    53
dvander@1203
    54
bool SqQuery::FetchMoreResults()
dvander@1203
    55
{
dvander@1203
    56
	/* We never have multiple result sets */
dvander@1203
    57
	return false;
dvander@1203
    58
}
dvander@1203
    59
dvander@1203
    60
void SqQuery::Destroy()
dvander@1203
    61
{
dvander@1203
    62
	delete this;
dvander@1203
    63
}
dvander@1203
    64
dvander@1203
    65
bool SqQuery::BindParamFloat(unsigned int param, float f)
dvander@1203
    66
{
dvander@1203
    67
	/* SQLite is 1 indexed */
dvander@1203
    68
	param++;
dvander@1203
    69
dvander@1203
    70
	if (param > m_ParamCount)
dvander@1203
    71
	{
dvander@1203
    72
		return false;
dvander@1203
    73
	}
dvander@1203
    74
dvander@1203
    75
	return (sqlite3_bind_double(m_pStmt, param, (double)f) == SQLITE_OK);
dvander@1203
    76
}
dvander@1203
    77
dvander@1203
    78
bool SqQuery::BindParamNull(unsigned int param)
dvander@1203
    79
{
dvander@1203
    80
	/* SQLite is 1 indexed */
dvander@1203
    81
	param++;
dvander@1203
    82
dvander@1203
    83
	if (param > m_ParamCount)
dvander@1203
    84
	{
dvander@1203
    85
		return false;
dvander@1203
    86
	}
dvander@1203
    87
dvander@1203
    88
	return (sqlite3_bind_null(m_pStmt, param) == SQLITE_OK);
dvander@1203
    89
}
dvander@1203
    90
dvander@1203
    91
bool SqQuery::BindParamString(unsigned int param, const char *text, bool copy)
dvander@1203
    92
{
dvander@1203
    93
	/* SQLite is 1 indexed */
dvander@1203
    94
	param++;
dvander@1203
    95
dvander@1203
    96
	if (param > m_ParamCount)
dvander@1203
    97
	{
dvander@1203
    98
		return false;
dvander@1203
    99
	}
dvander@1203
   100
dvander@1203
   101
	return (sqlite3_bind_text(m_pStmt, param, text, -1, copy ? SQLITE_TRANSIENT : SQLITE_STATIC) == SQLITE_OK);
dvander@1203
   102
}
dvander@1203
   103
dvander@1203
   104
bool SqQuery::BindParamInt(unsigned int param, int num, bool signd/* =true */)
dvander@1203
   105
{
dvander@1203
   106
	/* SQLite is 1 indexed */
dvander@1203
   107
	param++;
dvander@1203
   108
dvander@1203
   109
	if (param > m_ParamCount)
dvander@1203
   110
	{
dvander@1203
   111
		return false;
dvander@1203
   112
	}
dvander@1203
   113
dvander@1203
   114
	return (sqlite3_bind_int(m_pStmt, param, num) == SQLITE_OK);
dvander@1203
   115
}
dvander@1203
   116
dvander@1203
   117
bool SqQuery::BindParamBlob(unsigned int param, const void *data, size_t length, bool copy)
dvander@1203
   118
{
dvander@1203
   119
	/* SQLite is 1 indexed */
dvander@1203
   120
	param++;
dvander@1203
   121
dvander@1203
   122
	if (param > m_ParamCount)
dvander@1203
   123
	{
dvander@1203
   124
		return false;
dvander@1203
   125
	}
dvander@1203
   126
dvander@1203
   127
	return (sqlite3_bind_blob(m_pStmt, param, data, length, copy ? SQLITE_TRANSIENT : SQLITE_STATIC) == SQLITE_OK);
dvander@1203
   128
}
dvander@1203
   129
dvander@1203
   130
sqlite3_stmt *SqQuery::GetStmt()
dvander@1203
   131
{
dvander@1203
   132
	return m_pStmt;
dvander@1203
   133
}
dvander@1203
   134
dvander@1203
   135
bool SqQuery::Execute()
dvander@1203
   136
{
dvander@1203
   137
	int rc;
dvander@1203
   138
dvander@1210
   139
	/* If we don't have a result set and we have a column count, 
dvander@1210
   140
	 * create a result set pre-emptively.  This is in case there
dvander@1210
   141
	 * are no rows in the upcoming result set.
dvander@1210
   142
	 */
dvander@1210
   143
	if (!m_pResults && m_ColCount)
dvander@1210
   144
	{
dvander@1210
   145
		m_pResults = new SqResults(this);
dvander@1210
   146
	}
dvander@1210
   147
dvander@1203
   148
	/* If we've got results, throw them away */
dvander@1203
   149
	if (m_pResults)
dvander@1203
   150
	{
dvander@1203
   151
		m_pResults->ResetResultCount();
dvander@1203
   152
	}
dvander@1203
   153
dvander@1210
   154
	/* Fetch each row, if any */
dvander@1203
   155
	while ((rc = sqlite3_step(m_pStmt)) == SQLITE_ROW)
dvander@1203
   156
	{
dvander@1210
   157
		/* This should NEVER happen but we're being safe. */
dvander@1203
   158
		if (!m_pResults)
dvander@1203
   159
		{
dvander@1203
   160
			m_pResults = new SqResults(this);
dvander@1203
   161
		}
dvander@1203
   162
		m_pResults->PushResult();
dvander@1203
   163
	}
dvander@1203
   164
dvander@1203
   165
	sqlite3 *db = m_pParent->GetDb();
dvander@1203
   166
	if (rc != SQLITE_OK && rc != SQLITE_DONE && rc == sqlite3_errcode(db))
dvander@1203
   167
	{
dvander@1203
   168
		/* Something happened... */
dvander@1203
   169
		m_LastErrorCode = rc;
dvander@1203
   170
		m_LastError.assign(sqlite3_errmsg(db));
dvander@1203
   171
		m_AffectedRows = 0;
dvander@1203
   172
		m_InsertID = 0;
dvander@1203
   173
	} else {
dvander@1203
   174
		m_LastErrorCode = SQLITE_OK;
dvander@1203
   175
		m_AffectedRows = (unsigned int)sqlite3_changes(db);
dvander@1203
   176
		m_InsertID = (unsigned int)sqlite3_last_insert_rowid(db);
dvander@1203
   177
	}
dvander@1203
   178
dvander@1203
   179
	/* Reset everything for the next execute */
dvander@1203
   180
	sqlite3_reset(m_pStmt);
dvander@1203
   181
	sqlite3_clear_bindings(m_pStmt);
dvander@1203
   182
dvander@1203
   183
	return (m_LastErrorCode == SQLITE_OK);
dvander@1203
   184
}
dvander@1203
   185
dvander@1203
   186
const char *SqQuery::GetError(int *errCode/* =NULL */)
dvander@1203
   187
{
dvander@1203
   188
	if (errCode)
dvander@1203
   189
	{
dvander@1203
   190
		*errCode = m_LastErrorCode;
dvander@1203
   191
	}
dvander@1203
   192
	return m_LastError.c_str();
dvander@1203
   193
}
dvander@1203
   194
dvander@1203
   195
unsigned int SqQuery::GetAffectedRows()
dvander@1203
   196
{
dvander@1203
   197
	return m_AffectedRows;
dvander@1203
   198
}
dvander@1203
   199
dvander@1203
   200
unsigned int SqQuery::GetInsertID()
dvander@1203
   201
{
dvander@1203
   202
	return m_InsertID;
dvander@1203
   203
}
dvander@1203
   204
dvander@1203
   205