20#include "pqxxcursor.h"
21#include "pqxxconnection.h"
22#include "pqxxconnection_p.h"
24#include <kexidb/error.h>
25#include <kexidb/global.h>
35unsigned int pqxxSqlCursor_trans_num=0;
37static TQByteArray pgsqlByteaToByteArray(
const PQXX_FIELD_CLASS& r)
44pqxxSqlCursor::pqxxSqlCursor(
KexiDB::Connection* conn,
const TQString& statement, uint options):
45 Cursor(conn,statement, options)
52 m_implicityStarted =
false;
58 :
Cursor( conn, query, options )
65 m_implicityStarted =
false;
70pqxxSqlCursor::~pqxxSqlCursor()
77bool pqxxSqlCursor::drv_open()
81 if (!my_conn->is_open())
85 setError(ERR_NO_CONNECTION,i18n(
"No connection for cursor open operation specified"));
94 cur_name.sprintf(
"cursor_transaction%d", pqxxSqlCursor_trans_num++);
101 m_implicityStarted =
true;
104 m_res =
new pqxx::result(((
pqxxSqlConnection*)connection())->m_trans->data->exec(std::string(m_sql.utf8())));
111 m_fieldCount = m_res->columns() - (m_containsROWIDInfo ? 1 : 0);
114 m_records_in_buf = m_res->size();
115 m_buffering_completed =
true;
118 catch (
const std::exception &e)
120 setError(ERR_DB_SPECIFIC, TQString::fromUtf8( e.what()) );
121 KexiDBDrvWarn <<
"pqxxSqlCursor::drv_open:exception - " << TQString::fromUtf8( e.what() ) << endl;
129 if (m_implicityStarted) {
131 m_implicityStarted =
false;
139bool pqxxSqlCursor::drv_close()
157void pqxxSqlCursor::drv_getNextRecord()
160 if(at() < m_res->size() && at() >=0)
164 else if (at() >= m_res->size())
170 m_result = FetchError;
176void pqxxSqlCursor::drv_getPrevRecord()
180 if(at() < m_res->size() && at() >=0)
184 else if (at() >= m_res->size())
190 m_result = FetchError;
196TQVariant pqxxSqlCursor::value(uint pos)
198 if (pos < m_fieldCount)
206TQVariant pqxxSqlCursor::pValue(uint pos)
const
208 if (m_res->size() <= 0)
210 KexiDBDrvWarn <<
"pqxxSqlCursor::value - ERROR: result size not greater than 0" << endl;
214 if (pos>=(m_fieldCount+(m_containsROWIDInfo ? 1 : 0)))
220 KexiDB::Field *f = (m_fieldsExpanded && pos<TQMIN(m_fieldsExpanded->count(), m_fieldCount))
221 ? m_fieldsExpanded->at(pos)->field : 0;
228 if ((f->
isIntegerType()) || (!f && m_containsROWIDInfo && pos==m_fieldCount))
230 return (*m_res)[at()][pos].as(
int());
234 return TQString::fromUtf8((*m_res)[at()][pos].c_str());
238 return (*m_res)[at()][pos].as(
double());
242 return TQString((*m_res)[at()][pos].c_str()).lower() ==
"t" ? TQVariant(
true) : TQVariant(false);
244 else if (f->
typeGroup() == Field::BLOBGroup)
248 return ::pgsqlByteaToByteArray((*m_res)[at()][pos]);
252 return pgsqlCStrToVariant((*m_res)[at()][pos]);
257 return pgsqlCStrToVariant((*m_res)[at()][pos]);
260 return TQString::fromUtf8((*m_res)[at()][pos].c_str(), (*m_res)[at()][pos].size());
266const char** pqxxSqlCursor::rowData()
const
272 row = (
const char**)malloc(m_res->columns()+1);
273 row[m_res->columns()] = NULL;
274 if (at() >= 0 && at() < m_res->size())
276 for(
int i = 0; i < (int)m_res->columns(); i++)
278 row[i] = (
char*)malloc(strlen((*m_res)[at()][i].c_str())+1);
279 strcpy((
char*)(*m_res)[at()][i].c_str(), row[i]);
285 KexiDBDrvWarn <<
"pqxxSqlCursor::recordData: m_at is invalid" << endl;
292void pqxxSqlCursor::storeCurrentRow(
RowData &data)
const
296 if (m_res->size()<=0)
299 const uint realCount = m_fieldCount + (m_containsROWIDInfo ? 1 : 0);
300 data.resize(realCount);
302 for( uint i=0; i<realCount; i++)
310void pqxxSqlCursor::drv_clearServerResult()
319void pqxxSqlCursor::drv_appendCurrentRecordToBuffer()
327void pqxxSqlCursor::drv_bufferMovePointerNext()
335void pqxxSqlCursor::drv_bufferMovePointerPrev()
343void pqxxSqlCursor::drv_bufferMovePointerTo(TQ_LLONG to)
Provides database connection, allowing queries and data modification.
Provides database cursor functionality.
bool isFPNumericType() const
bool isIntegerType() const
static TypeGroup typeGroup(uint type)
KexiDB::QuerySchema provides information about database query.
High-level database connectivity library with database backend drivers.
TQValueVector< TQVariant > RowData
structure for storing single record with type information
KEXI_DB_EXPORT TQByteArray pgsqlByteaToByteArray(const char *data, int length)