amxmodx/dlls/pgsql/pgsql_amx.cpp
2004-06-29 05:54:53 +00:00

238 lines
3.0 KiB
C++
Executable File

#include "pgsql_amx.h"
using namespace std;
bool is_ipaddr(const char *IP)
{
do {
if ((int)(*(IP++)) > 0x37) {
return false;
}
} while (*IP);
return true;
}
SQL::SQL()
{
isFree = true;
}
SQL::~SQL()
{
if (!isFree)
Disconnect();
}
SQLResult::SQLResult()
{
isFree = true;
RowCount = 0;
}
SQLResult::~SQLResult()
{
if (!isFree)
FreeResult();
}
int SQL::Error(int code)
{
if (isFree)
return 0;
ErrorStr.assign(PQerrorMessage(cn));
ErrorCode = code;
return code;
}
int SQL::Connect(const char *host, const char *user, const char *pass, const char *base)
{
Username.assign(user);
Password.assign(pass);
Database.assign(base);
Host.assign(host);
isFree = false;
int err = 0;
if (is_ipaddr(Host.c_str())) {
cstr.assign("hostaddr = '");
} else {
cstr.assign("host = '");
}
cstr.append(Host);
cstr.append("' user = '");
cstr.append(Username);
cstr.append("' pass = '");
cstr.append(Password);
cstr.append("' name = '");
cstr.append(Database);
cstr.append("'");
cn = PQconnectdb(cstr.c_str());
if (PQstatus(cn) != CONNECTION_OK) {
Error(PQstatus(cn));
PQfinish(cn);
isFree = true;
return 0;
}
isFree = false;
return 1;
}
void SQL::Disconnect()
{
if (isFree)
return;
Host.clear();
Username.clear();
Password.clear();
Database.clear();
PQfinish(cn);
isFree = true;
}
int SQL::Query(const char *query)
{
if (isFree)
{
ErrorCode = -1;
return -1;
}
SQLResult *p = new SQLResult;
int ret = p->Query(this, query);
if (ret < 1)
{
delete p;
return ret;
}
unsigned int i = 0;
int id = -1;
for (i=0; i < Results.size(); i++)
{
if (Results[i]->isFree) {
id = i;
break;
}
}
if (id < 0) {
Results.push_back(p);
return Results.size();
} else {
SQLResult *r = Results[id];
Results[id] = p;
delete r;
return (id + 1);
}
}
int SQLResult::Query(SQL *cn, const char *query)
{
res = PQexec(cn->cn, query);
row = -1;
sql = cn;
int queryResult = PQresultStatus(res);
if (queryResult != PGRES_COMMAND_OK)
{
cn->Error(queryResult);
return -1;
}
RowCount = PQntuples(res);
if (RowCount < 1)
return 0;
int i = 0;
const char *fld;
for (i=0; i < PQnfields(res); i++)
{
fld = PQfname(res, i);
Fields.push_back(fld);
}
return 1;
}
bool SQLResult::Nextrow()
{
if (isFree)
return false;
if (row >= RowCount)
{
return false;
}
row++;
return true;
}
void SQLResult::FreeResult()
{
if (isFree)
return;
PQclear(res);
Fields.clear();
}
const char *SQLResult::GetField(unsigned int field)
{
if (field > (unsigned int)PQnfields(res))
{
sql->Error(-1);
sql->ErrorStr.assign("Invalid field.");
return 0;
}
return PQgetvalue(res, row, field);
}
const char *SQLResult::GetField(const char *field)
{
unsigned int fld;
int id = -1;
for (fld = 0; fld < Fields.size(); fld++)
{
if (strcmp(Fields[fld], field)==0)
{
id = fld;
break;
}
}
if (id == -1)
{
sql->Error(-1);
sql->ErrorStr.assign("Invalid field.");
return 0;
}
return PQgetvalue(res, row, id);
}
unsigned int SQLResult::NumRows()
{
if (isFree)
return 0;
return RowCount;
}