extensions/sqlite/driver/SqQuery.cpp
author David Anderson <dvander@alliedmods.net>
Sun Jul 29 14:56:24 2007 +0000 (2007-07-29)
changeset 1210 18e60c8737a2
parent 1203 633c25ce6405
child 1226 478550a4d5ec
permissions -rw-r--r--
fixed an sqlite bug where empty results would count as no result set
dvander@1203
     1
/**
dvander@1203
     2
 * vim: set ts=4 :
dvander@1203
     3
 * ===============================================================
dvander@1203
     4
 * SourceMod SQLite Driver Extension
dvander@1203
     5
 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
dvander@1203
     6
 * ===============================================================
dvander@1203
     7
 *
dvander@1203
     8
 * This program is free software; you can redistribute it and/or
dvander@1203
     9
 * modify it under the terms of the GNU General Public License
dvander@1203
    10
 * as published by the Free Software Foundation; either version 2
dvander@1203
    11
 * of the License, or (at your option) any later version.
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@1203
    16
 * 
dvander@1203
    17
 * You should have received a copy of the GNU General Public License
dvander@1203
    18
 * along with this program; if not, write to the Free Software
dvander@1203
    19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
dvander@1203
    20
 *
dvander@1203
    21
 * Version: $Id$
dvander@1203
    22
 */
dvander@1203
    23
dvander@1203
    24
#include "SqQuery.h"
dvander@1203
    25
dvander@1203
    26
SqQuery::SqQuery(SqDatabase *parent, sqlite3_stmt *stmt) : 
dvander@1203
    27
 m_pParent(parent), m_pStmt(stmt), m_pResults(NULL), m_AffectedRows(0), m_InsertID(0)
dvander@1203
    28
{
dvander@1203
    29
	m_ParamCount = sqlite3_bind_parameter_count(m_pStmt);
dvander@1210
    30
	m_ColCount = sqlite3_column_count(m_pStmt);
dvander@1203
    31
	m_pParent->IncReferenceCount();
dvander@1203
    32
}
dvander@1203
    33
dvander@1203
    34
SqQuery::~SqQuery()
dvander@1203
    35
{
dvander@1203
    36
	delete m_pResults;
dvander@1203
    37
	sqlite3_finalize(m_pStmt);
dvander@1203
    38
	m_pParent->Close();
dvander@1203
    39
}
dvander@1203
    40
dvander@1203
    41
IResultSet *SqQuery::GetResultSet()
dvander@1203
    42
{
dvander@1203
    43
	return m_pResults;
dvander@1203
    44
}
dvander@1203
    45
dvander@1203
    46
bool SqQuery::FetchMoreResults()
dvander@1203
    47
{
dvander@1203
    48
	/* We never have multiple result sets */
dvander@1203
    49
	return false;
dvander@1203
    50
}
dvander@1203
    51
dvander@1203
    52
void SqQuery::Destroy()
dvander@1203
    53
{
dvander@1203
    54
	delete this;
dvander@1203
    55
}
dvander@1203
    56
dvander@1203
    57
bool SqQuery::BindParamFloat(unsigned int param, float f)
dvander@1203
    58
{
dvander@1203
    59
	/* SQLite is 1 indexed */
dvander@1203
    60
	param++;
dvander@1203
    61
dvander@1203
    62
	if (param > m_ParamCount)
dvander@1203
    63
	{
dvander@1203
    64
		return false;
dvander@1203
    65
	}
dvander@1203
    66
dvander@1203
    67
	return (sqlite3_bind_double(m_pStmt, param, (double)f) == SQLITE_OK);
dvander@1203
    68
}
dvander@1203
    69
dvander@1203
    70
bool SqQuery::BindParamNull(unsigned int param)
dvander@1203
    71
{
dvander@1203
    72
	/* SQLite is 1 indexed */
dvander@1203
    73
	param++;
dvander@1203
    74
dvander@1203
    75
	if (param > m_ParamCount)
dvander@1203
    76
	{
dvander@1203
    77
		return false;
dvander@1203
    78
	}
dvander@1203
    79
dvander@1203
    80
	return (sqlite3_bind_null(m_pStmt, param) == SQLITE_OK);
dvander@1203
    81
}
dvander@1203
    82
dvander@1203
    83
bool SqQuery::BindParamString(unsigned int param, const char *text, bool copy)
dvander@1203
    84
{
dvander@1203
    85
	/* SQLite is 1 indexed */
dvander@1203
    86
	param++;
dvander@1203
    87
dvander@1203
    88
	if (param > m_ParamCount)
dvander@1203
    89
	{
dvander@1203
    90
		return false;
dvander@1203
    91
	}
dvander@1203
    92
dvander@1203
    93
	return (sqlite3_bind_text(m_pStmt, param, text, -1, copy ? SQLITE_TRANSIENT : SQLITE_STATIC) == SQLITE_OK);
dvander@1203
    94
}
dvander@1203
    95
dvander@1203
    96
bool SqQuery::BindParamInt(unsigned int param, int num, bool signd/* =true */)
dvander@1203
    97
{
dvander@1203
    98
	/* SQLite is 1 indexed */
dvander@1203
    99
	param++;
dvander@1203
   100
dvander@1203
   101
	if (param > m_ParamCount)
dvander@1203
   102
	{
dvander@1203
   103
		return false;
dvander@1203
   104
	}
dvander@1203
   105
dvander@1203
   106
	return (sqlite3_bind_int(m_pStmt, param, num) == SQLITE_OK);
dvander@1203
   107
}
dvander@1203
   108
dvander@1203
   109
bool SqQuery::BindParamBlob(unsigned int param, const void *data, size_t length, bool copy)
dvander@1203
   110
{
dvander@1203
   111
	/* SQLite is 1 indexed */
dvander@1203
   112
	param++;
dvander@1203
   113
dvander@1203
   114
	if (param > m_ParamCount)
dvander@1203
   115
	{
dvander@1203
   116
		return false;
dvander@1203
   117
	}
dvander@1203
   118
dvander@1203
   119
	return (sqlite3_bind_blob(m_pStmt, param, data, length, copy ? SQLITE_TRANSIENT : SQLITE_STATIC) == SQLITE_OK);
dvander@1203
   120
}
dvander@1203
   121
dvander@1203
   122
sqlite3_stmt *SqQuery::GetStmt()
dvander@1203
   123
{
dvander@1203
   124
	return m_pStmt;
dvander@1203
   125
}
dvander@1203
   126
dvander@1203
   127
bool SqQuery::Execute()
dvander@1203
   128
{
dvander@1203
   129
	int rc;
dvander@1203
   130
dvander@1210
   131
	/* If we don't have a result set and we have a column count, 
dvander@1210
   132
	 * create a result set pre-emptively.  This is in case there
dvander@1210
   133
	 * are no rows in the upcoming result set.
dvander@1210
   134
	 */
dvander@1210
   135
	if (!m_pResults && m_ColCount)
dvander@1210
   136
	{
dvander@1210
   137
		m_pResults = new SqResults(this);
dvander@1210
   138
	}
dvander@1210
   139
dvander@1203
   140
	/* If we've got results, throw them away */
dvander@1203
   141
	if (m_pResults)
dvander@1203
   142
	{
dvander@1203
   143
		m_pResults->ResetResultCount();
dvander@1203
   144
	}
dvander@1203
   145
dvander@1210
   146
	/* Fetch each row, if any */
dvander@1203
   147
	while ((rc = sqlite3_step(m_pStmt)) == SQLITE_ROW)
dvander@1203
   148
	{
dvander@1210
   149
		/* This should NEVER happen but we're being safe. */
dvander@1203
   150
		if (!m_pResults)
dvander@1203
   151
		{
dvander@1203
   152
			m_pResults = new SqResults(this);
dvander@1203
   153
		}
dvander@1203
   154
		m_pResults->PushResult();
dvander@1203
   155
	}
dvander@1203
   156
dvander@1203
   157
	sqlite3 *db = m_pParent->GetDb();
dvander@1203
   158
	if (rc != SQLITE_OK && rc != SQLITE_DONE && rc == sqlite3_errcode(db))
dvander@1203
   159
	{
dvander@1203
   160
		/* Something happened... */
dvander@1203
   161
		m_LastErrorCode = rc;
dvander@1203
   162
		m_LastError.assign(sqlite3_errmsg(db));
dvander@1203
   163
		m_AffectedRows = 0;
dvander@1203
   164
		m_InsertID = 0;
dvander@1203
   165
	} else {
dvander@1203
   166
		m_LastErrorCode = SQLITE_OK;
dvander@1203
   167
		m_AffectedRows = (unsigned int)sqlite3_changes(db);
dvander@1203
   168
		m_InsertID = (unsigned int)sqlite3_last_insert_rowid(db);
dvander@1203
   169
	}
dvander@1203
   170
dvander@1203
   171
	/* Reset everything for the next execute */
dvander@1203
   172
	sqlite3_reset(m_pStmt);
dvander@1203
   173
	sqlite3_clear_bindings(m_pStmt);
dvander@1203
   174
dvander@1203
   175
	return (m_LastErrorCode == SQLITE_OK);
dvander@1203
   176
}
dvander@1203
   177
dvander@1203
   178
const char *SqQuery::GetError(int *errCode/* =NULL */)
dvander@1203
   179
{
dvander@1203
   180
	if (errCode)
dvander@1203
   181
	{
dvander@1203
   182
		*errCode = m_LastErrorCode;
dvander@1203
   183
	}
dvander@1203
   184
	return m_LastError.c_str();
dvander@1203
   185
}
dvander@1203
   186
dvander@1203
   187
unsigned int SqQuery::GetAffectedRows()
dvander@1203
   188
{
dvander@1203
   189
	return m_AffectedRows;
dvander@1203
   190
}
dvander@1203
   191
dvander@1203
   192
unsigned int SqQuery::GetInsertID()
dvander@1203
   193
{
dvander@1203
   194
	return m_InsertID;
dvander@1203
   195
}
dvander@1203
   196
dvander@1203
   197