summaryrefslogtreecommitdiff
path: root/src/modules/extra/m_pgsql.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/extra/m_pgsql.cpp')
-rw-r--r--src/modules/extra/m_pgsql.cpp159
1 files changed, 150 insertions, 9 deletions
diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp
index 1e2a73f69..e36821cb9 100644
--- a/src/modules/extra/m_pgsql.cpp
+++ b/src/modules/extra/m_pgsql.cpp
@@ -175,34 +175,175 @@ public:
class PgSQLresult : public SQLresult
{
PGresult* res;
+ int currentrow;
+
+ SQLfieldList* fieldlist;
+ SQLfieldMap* fieldmap;
public:
PgSQLresult(Module* self, Module* to, PGresult* result)
- : SQLresult(self, to), res(result)
+ : SQLresult(self, to), res(result), currentrow(0), fieldlist(NULL), fieldmap(NULL)
{
int rows = PQntuples(res);
int cols = PQnfields(res);
log(DEBUG, "Created new PgSQL result; %d rows, %d columns", rows, cols);
+ }
+
+ ~PgSQLresult()
+ {
+ PQclear(res);
+ }
+
+ virtual int Rows()
+ {
+ return PQntuples(res);
+ }
+
+ virtual int Cols()
+ {
+ return PQnfields(res);
+ }
+
+ virtual std::string ColName(int column)
+ {
+ char* name = PQfname(res, column);
+
+ return (name) ? name : "";
+ }
+
+ virtual int ColNum(const std::string &column)
+ {
+ int n = PQfnumber(res, column.c_str());
- for (int r = 0; r < rows; r++)
+ if(n == -1)
{
- log(DEBUG, "Row %d:", r);
-
+ throw SQLbadColName();
+ }
+ else
+ {
+ return n;
+ }
+ }
+
+ virtual SQLfield GetValue(int row, int column)
+ {
+ char* v = PQgetvalue(res, row, column);
+
+ if(v)
+ {
+ return SQLfield(std::string(v, PQgetlength(res, row, column)), PQgetisnull(res, row, column));
+ }
+ else
+ {
+ log(DEBUG, "PQgetvalue returned a null pointer..nobody wants to tell us what this means");
+ throw SQLbadColName();
+ }
+ }
+
+ virtual SQLfieldList& GetRow()
+ {
+ /* In an effort to reduce overhead we don't actually allocate the list
+ * until the first time it's needed...so...
+ */
+ if(fieldlist)
+ {
+ fieldlist->clear();
+ }
+ else
+ {
+ fieldlist = new SQLfieldList;
+ }
+
+ if(currentrow < PQntuples(res))
+ {
+ int cols = PQnfields(res);
+
for(int i = 0; i < cols; i++)
{
- log(DEBUG, "\t[%s]: %s", PQfname(result, i), PQgetvalue(result, r, i));
+ fieldlist->push_back(GetValue(currentrow, i));
}
+
+ currentrow++;
}
+
+ return *fieldlist;
}
- ~PgSQLresult()
+ virtual SQLfieldMap& GetRowMap()
{
- PQclear(res);
+ /* In an effort to reduce overhead we don't actually allocate the map
+ * until the first time it's needed...so...
+ */
+ if(fieldmap)
+ {
+ fieldmap->clear();
+ }
+ else
+ {
+ fieldmap = new SQLfieldMap;
+ }
+
+ if(currentrow < PQntuples(res))
+ {
+ int cols = PQnfields(res);
+
+ for(int i = 0; i < cols; i++)
+ {
+ fieldmap->insert(std::make_pair(ColName(i), GetValue(currentrow, i)));
+ }
+
+ currentrow++;
+ }
+
+ return *fieldmap;
}
- virtual int Rows()
+ virtual SQLfieldList* GetRowPtr()
{
- return PQntuples(res);
+ SQLfieldList* fl = new SQLfieldList;
+
+ if(currentrow < PQntuples(res))
+ {
+ int cols = PQnfields(res);
+
+ for(int i = 0; i < cols; i++)
+ {
+ fl->push_back(GetValue(currentrow, i));
+ }
+
+ currentrow++;
+ }
+
+ return fl;
+ }
+
+ virtual SQLfieldMap* GetRowMapPtr()
+ {
+ SQLfieldMap* fm = new SQLfieldMap;
+
+ if(currentrow < PQntuples(res))
+ {
+ int cols = PQnfields(res);
+
+ for(int i = 0; i < cols; i++)
+ {
+ fm->insert(std::make_pair(ColName(i), GetValue(currentrow, i)));
+ }
+
+ currentrow++;
+ }
+
+ return fm;
+ }
+
+ virtual void Free(SQLfieldMap* fm)
+ {
+ DELETE(fm);
+ }
+
+ virtual void Free(SQLfieldList* fl)
+ {
+ DELETE(fl);
}
};