kexi
pqxxcursor.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "pqxxcursor.h"
00021 #include "pqxxconnection.h"
00022 #include "pqxxconnection_p.h"
00023
00024 #include <kexidb/error.h>
00025 #include <kexidb/global.h>
00026
00027 #include <klocale.h>
00028 #include <kdebug.h>
00029
00030 #include <cstdlib>
00031
00032 using namespace KexiDB;
00033
00034
00035 unsigned int pqxxSqlCursor_trans_num=0;
00036
00037 static QByteArray pgsqlByteaToByteArray(const pqxx::result::field& r)
00038 {
00039 return KexiDB::pgsqlByteaToByteArray(r.c_str(), r.size());
00040 }
00041
00042
00043
00044 pqxxSqlCursor::pqxxSqlCursor(KexiDB::Connection* conn, const QString& statement, uint options):
00045 Cursor(conn,statement, options)
00046 {
00047
00048 my_conn = static_cast<pqxxSqlConnection*>(conn)->d->pqxxsql;
00049 m_options = Buffered;
00050 m_res = 0;
00051
00052 m_implicityStarted = false;
00053 }
00054
00055
00056
00057 pqxxSqlCursor::pqxxSqlCursor(Connection* conn, QuerySchema& query, uint options )
00058 : Cursor( conn, query, options )
00059 {
00060
00061 my_conn = static_cast<pqxxSqlConnection*>(conn)->d->pqxxsql;
00062 m_options = Buffered;
00063 m_res = 0;
00064
00065 m_implicityStarted = false;
00066 }
00067
00068
00069
00070 pqxxSqlCursor::~pqxxSqlCursor()
00071 {
00072 close();
00073 }
00074
00075
00076
00077 bool pqxxSqlCursor::drv_open()
00078 {
00079
00080
00081 if (!my_conn->is_open())
00082 {
00084
00085 setError(ERR_NO_CONNECTION,i18n("No connection for cursor open operation specified"));
00086 return false;
00087 }
00088
00089 QCString cur_name;
00090
00091 try
00092 {
00093
00094 cur_name.sprintf("cursor_transaction%d", pqxxSqlCursor_trans_num++);
00095
00096
00097 if (!((pqxxSqlConnection*)connection())->m_trans) {
00098
00099
00100 (void)new pqxxTransactionData((pqxxSqlConnection*)connection(), true);
00101 m_implicityStarted = true;
00102 }
00103
00104 m_res = new pqxx::result(((pqxxSqlConnection*)connection())->m_trans->data->exec(std::string(m_sql.utf8())));
00105 ((pqxxSqlConnection*)connection())
00106 ->drv_commitTransaction(((pqxxSqlConnection*)connection())->m_trans);
00107
00108
00109
00110
00111 m_fieldCount = m_res->columns() - (m_containsROWIDInfo ? 1 : 0);
00112
00113 m_afterLast=false;
00114 m_records_in_buf = m_res->size();
00115 m_buffering_completed = true;
00116 return true;
00117 }
00118 catch (const std::exception &e)
00119 {
00120 setError(ERR_DB_SPECIFIC, QString::fromUtf8( e.what()) );
00121 KexiDBDrvWarn << "pqxxSqlCursor::drv_open:exception - " << QString::fromUtf8( e.what() ) << endl;
00122 }
00123 catch(...)
00124 {
00125 setError();
00126 }
00127
00128
00129 if (m_implicityStarted) {
00130 delete ((pqxxSqlConnection*)connection())->m_trans;
00131 m_implicityStarted = false;
00132 }
00133
00134 return false;
00135 }
00136
00137
00138
00139 bool pqxxSqlCursor::drv_close()
00140 {
00141
00142
00143 delete m_res;
00144 m_res = 0;
00145
00146
00147
00148
00149
00150
00151
00152 return true;
00153 }
00154
00155
00156
00157 void pqxxSqlCursor::drv_getNextRecord()
00158 {
00159
00160 if(at() < m_res->size() && at() >=0)
00161 {
00162 m_result = FetchOK;
00163 }
00164 else if (at() >= m_res->size())
00165 {
00166 m_result = FetchEnd;
00167 }
00168 else
00169 {
00170 m_result = FetchError;
00171 }
00172 }
00173
00174
00175
00176 void pqxxSqlCursor::drv_getPrevRecord()
00177 {
00178
00179
00180 if(at() < m_res->size() && at() >=0)
00181 {
00182 m_result = FetchOK;
00183 }
00184 else if (at() >= m_res->size())
00185 {
00186 m_result = FetchEnd;
00187 }
00188 else
00189 {
00190 m_result = FetchError;
00191 }
00192 }
00193
00194
00195
00196 QVariant pqxxSqlCursor::value(uint pos)
00197 {
00198 if (pos < m_fieldCount)
00199 return pValue(pos);
00200 else
00201 return QVariant();
00202 }
00203
00204
00205
00206 QVariant pqxxSqlCursor::pValue(uint pos)const
00207 {
00208 if (m_res->size() <= 0)
00209 {
00210 KexiDBDrvWarn << "pqxxSqlCursor::value - ERROR: result size not greater than 0" << endl;
00211 return QVariant();
00212 }
00213
00214 if (pos>=(m_fieldCount+(m_containsROWIDInfo ? 1 : 0)))
00215 {
00216
00217 return QVariant();
00218 }
00219
00220 KexiDB::Field *f = (m_fieldsExpanded && pos<QMIN(m_fieldsExpanded->count(), m_fieldCount))
00221 ? m_fieldsExpanded->at(pos)->field : 0;
00222
00223
00224
00225
00226 if (f)
00227 {
00228 if ((f->isIntegerType()) || (!f && m_containsROWIDInfo && pos==m_fieldCount))
00229 {
00230 return (*m_res)[at()][pos].as(int());
00231 }
00232 else if (f->isTextType())
00233 {
00234 return QString::fromUtf8((*m_res)[at()][pos].c_str());
00235 }
00236 else if (f->isFPNumericType())
00237 {
00238 return (*m_res)[at()][pos].as(double());
00239 }
00240 else if (f->typeGroup() == Field::BLOBGroup)
00241 {
00242
00243
00244 return ::pgsqlByteaToByteArray((*m_res)[at()][pos]);
00245 }
00246 }
00247 else
00248 {
00249 return pgsqlCStrToVariant((*m_res)[at()][pos]);
00250 }
00251
00252 return QString::fromUtf8((*m_res)[at()][pos].c_str(), (*m_res)[at()][pos].size());
00253 }
00254
00255
00256
00257
00258 const char** pqxxSqlCursor::rowData() const
00259 {
00260
00261
00262 const char** row;
00263
00264 row = (const char**)malloc(m_res->columns()+1);
00265 row[m_res->columns()] = NULL;
00266 if (at() >= 0 && at() < m_res->size())
00267 {
00268 for(int i = 0; i < (int)m_res->columns(); i++)
00269 {
00270 row[i] = (char*)malloc(strlen((*m_res)[at()][i].c_str())+1);
00271 strcpy((char*)(*m_res)[at()][i].c_str(), row[i]);
00272
00273 }
00274 }
00275 else
00276 {
00277 KexiDBDrvWarn << "pqxxSqlCursor::recordData: m_at is invalid" << endl;
00278 }
00279 return row;
00280 }
00281
00282
00283
00284 void pqxxSqlCursor::storeCurrentRow(RowData &data) const
00285 {
00286
00287
00288 if (m_res->size()<=0)
00289 return;
00290
00291 const uint realCount = m_fieldCount + (m_containsROWIDInfo ? 1 : 0);
00292 data.resize(realCount);
00293
00294 for( uint i=0; i<realCount; i++)
00295 {
00296 data[i] = pValue(i);
00297 }
00298 }
00299
00300
00301
00302 void pqxxSqlCursor::drv_clearServerResult()
00303 {
00305 }
00306
00307
00308
00309
00310
00311 void pqxxSqlCursor::drv_appendCurrentRecordToBuffer()
00312 {
00313
00314 }
00315
00316
00317
00318
00319 void pqxxSqlCursor::drv_bufferMovePointerNext()
00320 {
00321
00322 }
00323
00324
00325
00326
00327 void pqxxSqlCursor::drv_bufferMovePointerPrev()
00328 {
00329
00330 }
00331
00332
00333
00334
00335 void pqxxSqlCursor::drv_bufferMovePointerTo(Q_LLONG to)
00336 {
00337 Q_UNUSED(to);
00338 }
00339
|