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