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