amxmodx/dlls/sqlite/sqlite_amx.cpp
2006-05-16 21:20:14 +00:00

271 lines
4.8 KiB
C++
Executable File

#include "sqlite_amx.h"
SQL::SQL()
{
isFree = true;
sqlite = NULL;
}
SQL::~SQL()
{
if (!isFree)
Disconnect();
}
int SQL::Error()
{
if (sqlite == NULL)
return 0;
ErrorCode = sqlite3_errcode(sqlite);
ErrorStr.assign(sqlite3_errmsg(sqlite));
return ErrorCode;
}
int SQL::Connect(const char *base)
{
Database.assign(base);
isFree = false;
int err = 0;
this->ErrorCode = sqlite3_open(Database.c_str(), &sqlite);
if (ErrorCode != SQLITE_OK) {
err = Error();
if (err)
{
MF_Log("DB Connection failed(%d): %s", err, sqlite3_errmsg(sqlite));
sqlite3_close(sqlite);
isFree = true;
return 0;
}
}
isFree = false;
return 1;
}
void SQL::Disconnect()
{
Database.clear();
if (sqlite != NULL)
sqlite3_close(sqlite);
sqlite = NULL;
isFree = true;
}
int SQL::Query(const char *query)
{
if (sqlite == NULL || isFree)
{
ErrorCode = -1;
return -1;
}
unsigned int i = 0;
int id = -1;
for (i=0; i < Results.size(); i++)
{
if (Results[i]->isFree) {
id = i;
break;
}
}
if (id < 0) {
SQLResult *p = new SQLResult;
int ret = p->Query(this, query);
if (ret != 0)
{
delete p;
if (ret == -1)
return 0;
else
return -1;
} else {
Results.push_back(p);
#if defined _DEBUG
MF_PrintSrvConsole("***STORE: %d (push_back)\n", Results.size());
SQLResult::latestStoredResultId = Results.size();
#endif
return Results.size();
}
} else {
SQLResult *r = Results[id];
int ret = Results[id]->Query(this, query);
if (ret != 0)
{
if (ret == -1)
return 0;
else
return -1;
} else {
#if defined _DEBUG
MF_PrintSrvConsole("***STORE: %d\n", id + 1);
SQLResult::latestStoredResultId = id + 1;
#endif
return (id + 1);
}
}
}
SQLResult::SQLResult()
{
isFree = true;
m_fieldNames = 0;
m_hasData = false;
m_currentRow = -1;
m_data = NULL;
m_errorMsg = NULL;
m_rowCount = 0;
m_columnCount = 0;
}
SQLResult::~SQLResult()
{
if (!isFree)
FreeResult();
}
int SQLResult::Query(SQL *cn, const char *query)
{
/*
int sqlite3_get_table(
sqlite3*, // An open database
const char *sql, // SQL to be executed
char ***resultp, // Result written to a char *[] that this points to
int *nrow, // Number of result rows written here
int *ncolumn, // Number of result columns written here
char **errmsg // Error msg written here
);
*/
int rowCount, columnCount;
int result = sqlite3_get_table(cn->sqlite, query, &m_data, &rowCount, &columnCount, &m_errorMsg);
m_rowCount = rowCount;
m_columnCount = columnCount;
if (result != SQLITE_OK)
{
MF_Log("Query error: %s", m_errorMsg);
return 1;
}
else {
if (!m_rowCount)
return -1;
m_hasData = true;
this->m_fieldNames = new String[m_columnCount];
for (unsigned int i = 0; i < m_columnCount; i++)
m_fieldNames[i].assign(m_data[i]);
#if defined _DEBUG
MF_PrintSrvConsole("SQLite: Select query returned %d rows in %d columns.\n", m_rowCount, m_columnCount);
for (unsigned int i = 0; i < m_columnCount; i++) {
MF_PrintSrvConsole("%15s", m_fieldNames[i].c_str());
}
MF_PrintSrvConsole("\n");
for (unsigned int i = 0; i < m_rowCount; i++) {
for (unsigned int j = 0; j < m_columnCount; j++) {
MF_PrintSrvConsole("%15s", m_data[(1 + i) * m_columnCount + j]);
}
MF_PrintSrvConsole("\n");
}
#endif
}
isFree = false;
return 0; // Return 0 here? and 1 on error... 0's get stored and 1's get deleted
}
bool SQLResult::Nextrow()
{
if (isFree)
return false;
if (++m_currentRow >= (int)this->m_rowCount) {
//m_currentRow = -1; <-- this is probably bad and inconsistent...
//FreeResult(); <-- this is probably bad and inconsistent... freeing should be the responsibility of the scripter
return false;
}
return true;
}
void SQLResult::FreeResult()
{
if (isFree)
return;
/*
#if defined _DEBUG
MF_PrintSrvConsole("FREEING a result!\n");
#endif
*/
isFree = true;
if (m_hasData) {
sqlite3_free_table(m_data);
delete [] this->m_fieldNames;
m_hasData = false;
}
m_currentRow = -1;
m_columnCount = 0;
m_rowCount = 0;
}
const char *SQLResult::GetField(unsigned int field)
{
if (isFree || field >= m_columnCount || m_currentRow < 0 || m_currentRow >= (int)m_rowCount)
{
return NULL;
}
char *data = m_data[(m_currentRow + 1) * m_columnCount + field];
return (data ? data : "");
}
const char *SQLResult::GetField(const char *field)
{
unsigned int i = 0;
int id = -1;
if (field == NULL)
return NULL;
for (i=0; i < m_columnCount; i++)
{
if (strcmp(m_fieldNames[i].c_str(), field) == 0)
{
id = i;
break;
}
}
if (id<0 || id>=(int)m_columnCount)
{
return NULL;
}
return GetField(id);
}
unsigned int SQLResult::NumRows()
{
if (isFree)
return 0;
return m_rowCount;
}
#if defined _DEBUG
unsigned int SQLResult::latestStoredResultId = 0;
#endif