238 lines
3.0 KiB
C++
Executable File
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);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|