qsql: apply Qt's PIMPL idiom to Q*ResultPrivate
QResult and QResultPrivate are not derived from QObject and QObjectPrivate respectively, but can still benefit from Qt's PIMPL idiom. There are several interrelated aspects to this: - Base all driver ResultPrivate classes on QResultPrivate. Previously, each level in the Result hierarchy tended to keep its own private data class. - The ResultPrivate class initializes its own Result (q_ptr) and Driver members. This ensures that these pointers are correctly set in time for the ResultPrivate constructors and Result constructors. This is more efficient and makes it a lot easier to follow what's being allocated, initialized, and cleaned-up. - Use macros Q_DECLARE_PRIVATE, Q_DECLARE_PUBLIC, Q_D, and Q_Q for access to and from ResultPrivate objects. - ResultPrivate classes refer frequently to their counterpart DriverPrivate. Various patterns were used to do this. Now Q_DECLARE_SQLDRIVER_PRIVATE arranges this uniformly while hiding ugly casting. It creates a public method in the ResultPrivate returning the correctly typed pointer to the corresponding DriverPrivate object. Since the method is public, the Result class and helper classes and functions can also use it. - The explicit const is removed from QResultPrivate::sqldriver, even though it is treated (mostly) like a const within the context of Result and ResultPrivate. This is the same pattern seen in Qt's PIMPL idiom. The macro created getter methods take care of const. - qsql_mysql was using a signal/slot connection to zero its own copy of the driver pointer when the driver was destroyed. This is no longer necessary. Change-Id: Ida4933bc92fb3e9a05ea4b53b48085894734e36e Reviewed-by: Israel Lins Albuquerque <israelins85@yahoo.com.br> Reviewed-by: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
parent
f5f47987ce
commit
d79ae90466
@ -66,6 +66,8 @@ static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL
|
|||||||
|
|
||||||
class QDB2DriverPrivate : public QSqlDriverPrivate
|
class QDB2DriverPrivate : public QSqlDriverPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QDB2Driver)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QDB2DriverPrivate() : QSqlDriverPrivate(), hEnv(0), hDbc(0) { dbmsType = QSqlDriver::DB2; }
|
QDB2DriverPrivate() : QSqlDriverPrivate(), hEnv(0), hDbc(0) { dbmsType = QSqlDriver::DB2; }
|
||||||
SQLHANDLE hEnv;
|
SQLHANDLE hEnv;
|
||||||
@ -77,8 +79,10 @@ class QDB2ResultPrivate;
|
|||||||
|
|
||||||
class QDB2Result: public QSqlResult
|
class QDB2Result: public QSqlResult
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QDB2Result)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QDB2Result(const QDB2Driver *dr, const QDB2DriverPrivate *dp);
|
QDB2Result(const QDB2Driver *drv);
|
||||||
~QDB2Result();
|
~QDB2Result();
|
||||||
bool prepare(const QString &query) Q_DECL_OVERRIDE;
|
bool prepare(const QString &query) Q_DECL_OVERRIDE;
|
||||||
bool exec() Q_DECL_OVERRIDE;
|
bool exec() Q_DECL_OVERRIDE;
|
||||||
@ -98,15 +102,17 @@ protected:
|
|||||||
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
||||||
void detachFromResultSet() Q_DECL_OVERRIDE;
|
void detachFromResultSet() Q_DECL_OVERRIDE;
|
||||||
bool nextResult() Q_DECL_OVERRIDE;
|
bool nextResult() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
|
||||||
QDB2ResultPrivate *d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QDB2ResultPrivate
|
class QDB2ResultPrivate: public QSqlResultPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QDB2Result)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0)
|
Q_DECLARE_SQLDRIVER_PRIVATE(QDB2Driver)
|
||||||
|
QDB2ResultPrivate(QDB2Result *q, const QDB2Driver *drv)
|
||||||
|
: QSqlResultPrivate(q, drv),
|
||||||
|
hStmt(0)
|
||||||
{}
|
{}
|
||||||
~QDB2ResultPrivate()
|
~QDB2ResultPrivate()
|
||||||
{
|
{
|
||||||
@ -125,7 +131,6 @@ public:
|
|||||||
valueCache.clear();
|
valueCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QDB2DriverPrivate* dp;
|
|
||||||
SQLHANDLE hStmt;
|
SQLHANDLE hStmt;
|
||||||
QSqlRecord recInf;
|
QSqlRecord recInf;
|
||||||
QVector<QVariant*> valueCache;
|
QVector<QVariant*> valueCache;
|
||||||
@ -171,8 +176,8 @@ static QString qDB2Warn(const QDB2DriverPrivate* d)
|
|||||||
|
|
||||||
static QString qDB2Warn(const QDB2ResultPrivate* d)
|
static QString qDB2Warn(const QDB2ResultPrivate* d)
|
||||||
{
|
{
|
||||||
return (qWarnDB2Handle(SQL_HANDLE_ENV, d->dp->hEnv) + QLatin1Char(' ')
|
return (qWarnDB2Handle(SQL_HANDLE_ENV, d->drv_d_func()->hEnv) + QLatin1Char(' ')
|
||||||
+ qWarnDB2Handle(SQL_HANDLE_DBC, d->dp->hDbc)
|
+ qWarnDB2Handle(SQL_HANDLE_DBC, d->drv_d_func()->hDbc)
|
||||||
+ qWarnDB2Handle(SQL_HANDLE_STMT, d->hStmt));
|
+ qWarnDB2Handle(SQL_HANDLE_STMT, d->hStmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,7 +502,7 @@ static bool qMakeStatement(QDB2ResultPrivate* d, bool forwardOnly, bool setForwa
|
|||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
if (!d->hStmt) {
|
if (!d->hStmt) {
|
||||||
r = SQLAllocHandle(SQL_HANDLE_STMT,
|
r = SQLAllocHandle(SQL_HANDLE_STMT,
|
||||||
d->dp->hDbc,
|
d->drv_d_func()->hDbc,
|
||||||
&d->hStmt);
|
&d->hStmt);
|
||||||
if (r != SQL_SUCCESS) {
|
if (r != SQL_SUCCESS) {
|
||||||
qSqlWarning(QLatin1String("QDB2Result::reset: Unable to allocate statement handle"), d);
|
qSqlWarning(QLatin1String("QDB2Result::reset: Unable to allocate statement handle"), d);
|
||||||
@ -536,30 +541,31 @@ static bool qMakeStatement(QDB2ResultPrivate* d, bool forwardOnly, bool setForwa
|
|||||||
|
|
||||||
QVariant QDB2Result::handle() const
|
QVariant QDB2Result::handle() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QDB2Result);
|
||||||
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
|
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************/
|
/************************************/
|
||||||
|
|
||||||
QDB2Result::QDB2Result(const QDB2Driver* dr, const QDB2DriverPrivate* dp)
|
QDB2Result::QDB2Result(const QDB2Driver *drv)
|
||||||
: QSqlResult(dr)
|
: QSqlResult(*new QDB2ResultPrivate(this, drv))
|
||||||
{
|
{
|
||||||
d = new QDB2ResultPrivate(dp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QDB2Result::~QDB2Result()
|
QDB2Result::~QDB2Result()
|
||||||
{
|
{
|
||||||
|
Q_D(const QDB2Result);
|
||||||
if (d->hStmt) {
|
if (d->hStmt) {
|
||||||
SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
|
SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
|
||||||
if (r != SQL_SUCCESS)
|
if (r != SQL_SUCCESS)
|
||||||
qSqlWarning(QLatin1String("QDB2Driver: Unable to free statement handle ")
|
qSqlWarning(QLatin1String("QDB2Driver: Unable to free statement handle ")
|
||||||
+ QString::number(r), d);
|
+ QString::number(r), d);
|
||||||
}
|
}
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QDB2Result::reset (const QString& query)
|
bool QDB2Result::reset (const QString& query)
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
@ -596,6 +602,7 @@ bool QDB2Result::reset (const QString& query)
|
|||||||
|
|
||||||
bool QDB2Result::prepare(const QString& query)
|
bool QDB2Result::prepare(const QString& query)
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
@ -620,6 +627,7 @@ bool QDB2Result::prepare(const QString& query)
|
|||||||
|
|
||||||
bool QDB2Result::exec()
|
bool QDB2Result::exec()
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
QList<QByteArray> tmpStorage; // holds temporary ptrs
|
QList<QByteArray> tmpStorage; // holds temporary ptrs
|
||||||
QVarLengthArray<SQLINTEGER, 32> indicators(boundValues().count());
|
QVarLengthArray<SQLINTEGER, 32> indicators(boundValues().count());
|
||||||
|
|
||||||
@ -871,6 +879,7 @@ bool QDB2Result::exec()
|
|||||||
|
|
||||||
bool QDB2Result::fetch(int i)
|
bool QDB2Result::fetch(int i)
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
if (isForwardOnly() && i < at())
|
if (isForwardOnly() && i < at())
|
||||||
return false;
|
return false;
|
||||||
if (i == at())
|
if (i == at())
|
||||||
@ -905,6 +914,7 @@ bool QDB2Result::fetch(int i)
|
|||||||
|
|
||||||
bool QDB2Result::fetchNext()
|
bool QDB2Result::fetchNext()
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
d->clearValueCache();
|
d->clearValueCache();
|
||||||
r = SQLFetchScroll(d->hStmt,
|
r = SQLFetchScroll(d->hStmt,
|
||||||
@ -922,6 +932,7 @@ bool QDB2Result::fetchNext()
|
|||||||
|
|
||||||
bool QDB2Result::fetchFirst()
|
bool QDB2Result::fetchFirst()
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
if (isForwardOnly() && at() != QSql::BeforeFirstRow)
|
if (isForwardOnly() && at() != QSql::BeforeFirstRow)
|
||||||
return false;
|
return false;
|
||||||
if (isForwardOnly())
|
if (isForwardOnly())
|
||||||
@ -943,6 +954,7 @@ bool QDB2Result::fetchFirst()
|
|||||||
|
|
||||||
bool QDB2Result::fetchLast()
|
bool QDB2Result::fetchLast()
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
d->clearValueCache();
|
d->clearValueCache();
|
||||||
|
|
||||||
int i = at();
|
int i = at();
|
||||||
@ -974,6 +986,7 @@ bool QDB2Result::fetchLast()
|
|||||||
|
|
||||||
QVariant QDB2Result::data(int field)
|
QVariant QDB2Result::data(int field)
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
if (field >= d->recInf.count()) {
|
if (field >= d->recInf.count()) {
|
||||||
qWarning("QDB2Result::data: column %d out of range", field);
|
qWarning("QDB2Result::data: column %d out of range", field);
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@ -1080,6 +1093,7 @@ QVariant QDB2Result::data(int field)
|
|||||||
|
|
||||||
bool QDB2Result::isNull(int i)
|
bool QDB2Result::isNull(int i)
|
||||||
{
|
{
|
||||||
|
Q_D(const QDB2Result);
|
||||||
if (i >= d->valueCache.size())
|
if (i >= d->valueCache.size())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1090,6 +1104,7 @@ bool QDB2Result::isNull(int i)
|
|||||||
|
|
||||||
int QDB2Result::numRowsAffected()
|
int QDB2Result::numRowsAffected()
|
||||||
{
|
{
|
||||||
|
Q_D(const QDB2Result);
|
||||||
SQLINTEGER affectedRowCount = 0;
|
SQLINTEGER affectedRowCount = 0;
|
||||||
SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
|
SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
|
||||||
if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
|
if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
|
||||||
@ -1106,6 +1121,7 @@ int QDB2Result::size()
|
|||||||
|
|
||||||
QSqlRecord QDB2Result::record() const
|
QSqlRecord QDB2Result::record() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QDB2Result);
|
||||||
if (isActive())
|
if (isActive())
|
||||||
return d->recInf;
|
return d->recInf;
|
||||||
return QSqlRecord();
|
return QSqlRecord();
|
||||||
@ -1113,6 +1129,7 @@ QSqlRecord QDB2Result::record() const
|
|||||||
|
|
||||||
bool QDB2Result::nextResult()
|
bool QDB2Result::nextResult()
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
d->recInf.clear();
|
d->recInf.clear();
|
||||||
@ -1148,6 +1165,7 @@ void QDB2Result::virtual_hook(int id, void *data)
|
|||||||
|
|
||||||
void QDB2Result::detachFromResultSet()
|
void QDB2Result::detachFromResultSet()
|
||||||
{
|
{
|
||||||
|
Q_D(QDB2Result);
|
||||||
if (d->hStmt)
|
if (d->hStmt)
|
||||||
SQLCloseCursor(d->hStmt);
|
SQLCloseCursor(d->hStmt);
|
||||||
}
|
}
|
||||||
@ -1309,8 +1327,7 @@ void QDB2Driver::close()
|
|||||||
|
|
||||||
QSqlResult *QDB2Driver::createResult() const
|
QSqlResult *QDB2Driver::createResult() const
|
||||||
{
|
{
|
||||||
Q_D(const QDB2Driver);
|
return new QDB2Result(this);
|
||||||
return new QDB2Result(this, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlRecord QDB2Driver::record(const QString& tableName) const
|
QSqlRecord QDB2Driver::record(const QString& tableName) const
|
||||||
|
@ -63,6 +63,8 @@ class Q_EXPORT_SQLDRIVER_DB2 QDB2Driver : public QSqlDriver
|
|||||||
{
|
{
|
||||||
Q_DECLARE_PRIVATE(QDB2Driver)
|
Q_DECLARE_PRIVATE(QDB2Driver)
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
friend class QDB2ResultPrivate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QDB2Driver(QObject* parent = 0);
|
explicit QDB2Driver(QObject* parent = 0);
|
||||||
QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent = 0);
|
QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent = 0);
|
||||||
|
@ -345,7 +345,7 @@ class QIBaseResultPrivate;
|
|||||||
|
|
||||||
class QIBaseResult : public QSqlCachedResult
|
class QIBaseResult : public QSqlCachedResult
|
||||||
{
|
{
|
||||||
friend class QIBaseResultPrivate;
|
Q_DECLARE_PRIVATE(QIBaseResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QIBaseResult(const QIBaseDriver* db);
|
explicit QIBaseResult(const QIBaseDriver* db);
|
||||||
@ -361,20 +361,22 @@ protected:
|
|||||||
int size() Q_DECL_OVERRIDE;
|
int size() Q_DECL_OVERRIDE;
|
||||||
int numRowsAffected() Q_DECL_OVERRIDE;
|
int numRowsAffected() Q_DECL_OVERRIDE;
|
||||||
QSqlRecord record() const Q_DECL_OVERRIDE;
|
QSqlRecord record() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
|
||||||
QIBaseResultPrivate* d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QIBaseResultPrivate
|
class QIBaseResultPrivate: public QSqlCachedResultPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QIBaseResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QIBaseResultPrivate(QIBaseResult *d, const QIBaseDriver *ddb);
|
Q_DECLARE_SQLDRIVER_PRIVATE(QIBaseDriver)
|
||||||
|
|
||||||
|
QIBaseResultPrivate(QIBaseResult *q, const QIBaseDriver *drv);
|
||||||
~QIBaseResultPrivate() { cleanup(); }
|
~QIBaseResultPrivate() { cleanup(); }
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
bool isError(const char *msg, QSqlError::ErrorType typ = QSqlError::UnknownError)
|
bool isError(const char *msg, QSqlError::ErrorType typ = QSqlError::UnknownError)
|
||||||
{
|
{
|
||||||
|
Q_Q(QIBaseResult);
|
||||||
QString imsg;
|
QString imsg;
|
||||||
ISC_LONG sqlcode;
|
ISC_LONG sqlcode;
|
||||||
if (!getIBaseError(imsg, status, sqlcode, tc))
|
if (!getIBaseError(imsg, status, sqlcode, tc))
|
||||||
@ -395,8 +397,6 @@ public:
|
|||||||
bool writeArray(int i, const QList<QVariant> &list);
|
bool writeArray(int i, const QList<QVariant> &list);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QIBaseResult *q;
|
|
||||||
const QIBaseDriver *db;
|
|
||||||
ISC_STATUS status[20];
|
ISC_STATUS status[20];
|
||||||
isc_tr_handle trans;
|
isc_tr_handle trans;
|
||||||
//indicator whether we have a local transaction or a transaction on driver level
|
//indicator whether we have a local transaction or a transaction on driver level
|
||||||
@ -410,14 +410,22 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
QIBaseResultPrivate::QIBaseResultPrivate(QIBaseResult *d, const QIBaseDriver *ddb):
|
QIBaseResultPrivate::QIBaseResultPrivate(QIBaseResult *q, const QIBaseDriver *drv)
|
||||||
q(d), db(ddb), trans(0), stmt(0), ibase(ddb->d_func()->ibase), sqlda(0), inda(0), queryType(-1), tc(ddb->d_func()->tc)
|
: QSqlCachedResultPrivate(q, drv),
|
||||||
|
trans(0),
|
||||||
|
localTransaction(!drv_d_func()->ibase),
|
||||||
|
stmt(0),
|
||||||
|
ibase(drv_d_func()->ibase),
|
||||||
|
sqlda(0),
|
||||||
|
inda(0),
|
||||||
|
queryType(-1),
|
||||||
|
tc(drv_d_func()->tc)
|
||||||
{
|
{
|
||||||
localTransaction = (ddb->d_func()->ibase == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIBaseResultPrivate::cleanup()
|
void QIBaseResultPrivate::cleanup()
|
||||||
{
|
{
|
||||||
|
Q_Q(QIBaseResult);
|
||||||
commit();
|
commit();
|
||||||
if (!localTransaction)
|
if (!localTransaction)
|
||||||
trans = 0;
|
trans = 0;
|
||||||
@ -779,6 +787,7 @@ static char* createArrayBuffer(char *buffer, const QList<QVariant> &list,
|
|||||||
|
|
||||||
bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
|
bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
|
||||||
{
|
{
|
||||||
|
Q_Q(QIBaseResult);
|
||||||
QString error;
|
QString error;
|
||||||
ISC_QUAD *arrayId = (ISC_QUAD*) inda->sqlvar[column].sqldata;
|
ISC_QUAD *arrayId = (ISC_QUAD*) inda->sqlvar[column].sqldata;
|
||||||
ISC_ARRAY_DESC desc;
|
ISC_ARRAY_DESC desc;
|
||||||
@ -854,9 +863,9 @@ bool QIBaseResultPrivate::transaction()
|
|||||||
{
|
{
|
||||||
if (trans)
|
if (trans)
|
||||||
return true;
|
return true;
|
||||||
if (db->d_func()->trans) {
|
if (drv_d_func()->trans) {
|
||||||
localTransaction = false;
|
localTransaction = false;
|
||||||
trans = db->d_func()->trans;
|
trans = drv_d_func()->trans;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
localTransaction = true;
|
localTransaction = true;
|
||||||
@ -887,19 +896,18 @@ bool QIBaseResultPrivate::commit()
|
|||||||
|
|
||||||
//////////
|
//////////
|
||||||
|
|
||||||
QIBaseResult::QIBaseResult(const QIBaseDriver* db):
|
QIBaseResult::QIBaseResult(const QIBaseDriver *db)
|
||||||
QSqlCachedResult(db)
|
: QSqlCachedResult(*new QIBaseResultPrivate(this, db))
|
||||||
{
|
{
|
||||||
d = new QIBaseResultPrivate(this, db);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QIBaseResult::~QIBaseResult()
|
QIBaseResult::~QIBaseResult()
|
||||||
{
|
{
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QIBaseResult::prepare(const QString& query)
|
bool QIBaseResult::prepare(const QString& query)
|
||||||
{
|
{
|
||||||
|
Q_D(QIBaseResult);
|
||||||
// qDebug("prepare: %s", qPrintable(query));
|
// qDebug("prepare: %s", qPrintable(query));
|
||||||
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
|
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
|
||||||
return false;
|
return false;
|
||||||
@ -976,6 +984,7 @@ bool QIBaseResult::prepare(const QString& query)
|
|||||||
|
|
||||||
bool QIBaseResult::exec()
|
bool QIBaseResult::exec()
|
||||||
{
|
{
|
||||||
|
Q_D(QIBaseResult);
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
if (!d->trans)
|
if (!d->trans)
|
||||||
@ -1113,6 +1122,7 @@ bool QIBaseResult::reset (const QString& query)
|
|||||||
|
|
||||||
bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
|
bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
|
||||||
{
|
{
|
||||||
|
Q_D(QIBaseResult);
|
||||||
ISC_STATUS stat = 0;
|
ISC_STATUS stat = 0;
|
||||||
|
|
||||||
// Stored Procedures are special - they populate our d->sqlda when executing,
|
// Stored Procedures are special - they populate our d->sqlda when executing,
|
||||||
@ -1307,6 +1317,7 @@ int QIBaseResult::size()
|
|||||||
|
|
||||||
int QIBaseResult::numRowsAffected()
|
int QIBaseResult::numRowsAffected()
|
||||||
{
|
{
|
||||||
|
Q_D(QIBaseResult);
|
||||||
static char acCountInfo[] = {isc_info_sql_records};
|
static char acCountInfo[] = {isc_info_sql_records};
|
||||||
char cCountType;
|
char cCountType;
|
||||||
bool bIsProcedure = false;
|
bool bIsProcedure = false;
|
||||||
@ -1361,6 +1372,7 @@ int QIBaseResult::numRowsAffected()
|
|||||||
|
|
||||||
QSqlRecord QIBaseResult::record() const
|
QSqlRecord QIBaseResult::record() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QIBaseResult);
|
||||||
QSqlRecord rec;
|
QSqlRecord rec;
|
||||||
if (!isActive() || !d->sqlda)
|
if (!isActive() || !d->sqlda)
|
||||||
return rec;
|
return rec;
|
||||||
@ -1400,6 +1412,7 @@ QSqlRecord QIBaseResult::record() const
|
|||||||
|
|
||||||
QVariant QIBaseResult::handle() const
|
QVariant QIBaseResult::handle() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QIBaseResult);
|
||||||
return QVariant(qRegisterMetaType<isc_stmt_handle>("isc_stmt_handle"), &d->stmt);
|
return QVariant(qRegisterMetaType<isc_stmt_handle>("isc_stmt_handle"), &d->stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QMYSQLDriverPrivate : public QSqlDriverPrivate
|
class QMYSQLDriverPrivate : public QSqlDriverPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QMYSQLDriver)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0),
|
QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0),
|
||||||
#ifndef QT_NO_TEXTCODEC
|
#ifndef QT_NO_TEXTCODEC
|
||||||
@ -160,8 +162,9 @@ class QMYSQLResultPrivate;
|
|||||||
|
|
||||||
class QMYSQLResult : public QSqlResult
|
class QMYSQLResult : public QSqlResult
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QMYSQLResult)
|
||||||
friend class QMYSQLDriver;
|
friend class QMYSQLDriver;
|
||||||
friend class QMYSQLResultPrivate;
|
|
||||||
public:
|
public:
|
||||||
explicit QMYSQLResult(const QMYSQLDriver *db);
|
explicit QMYSQLResult(const QMYSQLDriver *db);
|
||||||
~QMYSQLResult();
|
~QMYSQLResult();
|
||||||
@ -187,28 +190,28 @@ protected:
|
|||||||
bool prepare(const QString &stmt) Q_DECL_OVERRIDE;
|
bool prepare(const QString &stmt) Q_DECL_OVERRIDE;
|
||||||
bool exec() Q_DECL_OVERRIDE;
|
bool exec() Q_DECL_OVERRIDE;
|
||||||
#endif
|
#endif
|
||||||
private:
|
|
||||||
QMYSQLResultPrivate *d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QMYSQLResultPrivate : public QObject
|
class QMYSQLResultPrivate: public QSqlResultPrivate
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_DECLARE_PUBLIC(QMYSQLResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QMYSQLResultPrivate(const QMYSQLDriver* dp, const QMYSQLResult* d) : driver(dp), result(0), q(d),
|
Q_DECLARE_SQLDRIVER_PRIVATE(QMYSQLDriver)
|
||||||
rowsAffected(0), hasBlobs(false)
|
|
||||||
|
QMYSQLResultPrivate(QMYSQLResult *q, const QMYSQLDriver *drv)
|
||||||
|
: QSqlResultPrivate(q, drv),
|
||||||
|
result(0),
|
||||||
|
rowsAffected(0),
|
||||||
|
hasBlobs(false)
|
||||||
#if MYSQL_VERSION_ID >= 40108
|
#if MYSQL_VERSION_ID >= 40108
|
||||||
, stmt(0), meta(0), inBinds(0), outBinds(0)
|
, stmt(0), meta(0), inBinds(0), outBinds(0)
|
||||||
#endif
|
#endif
|
||||||
, preparedQuery(false)
|
, preparedQuery(false)
|
||||||
{
|
{ }
|
||||||
connect(dp, SIGNAL(destroyed()), this, SLOT(driverDestroyed()));
|
|
||||||
}
|
|
||||||
|
|
||||||
const QMYSQLDriver* driver;
|
|
||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
const QMYSQLResult* q;
|
|
||||||
|
|
||||||
int rowsAffected;
|
int rowsAffected;
|
||||||
|
|
||||||
@ -240,9 +243,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool preparedQuery;
|
bool preparedQuery;
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void driverDestroyed() { driver = NULL; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_TEXTCODEC
|
#ifndef QT_NO_TEXTCODEC
|
||||||
@ -431,19 +431,18 @@ bool QMYSQLResultPrivate::bindInValues()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
QMYSQLResult::QMYSQLResult(const QMYSQLDriver* db)
|
QMYSQLResult::QMYSQLResult(const QMYSQLDriver* db)
|
||||||
: QSqlResult(db)
|
: QSqlResult(*new QMYSQLResultPrivate(this, db))
|
||||||
{
|
{
|
||||||
d = new QMYSQLResultPrivate(db, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMYSQLResult::~QMYSQLResult()
|
QMYSQLResult::~QMYSQLResult()
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QMYSQLResult::handle() const
|
QVariant QMYSQLResult::handle() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QMYSQLResult);
|
||||||
#if MYSQL_VERSION_ID >= 40108
|
#if MYSQL_VERSION_ID >= 40108
|
||||||
if(d->preparedQuery)
|
if(d->preparedQuery)
|
||||||
return d->meta ? QVariant::fromValue(d->meta) : QVariant::fromValue(d->stmt);
|
return d->meta ? QVariant::fromValue(d->meta) : QVariant::fromValue(d->stmt);
|
||||||
@ -454,14 +453,15 @@ QVariant QMYSQLResult::handle() const
|
|||||||
|
|
||||||
void QMYSQLResult::cleanup()
|
void QMYSQLResult::cleanup()
|
||||||
{
|
{
|
||||||
|
Q_D(QMYSQLResult);
|
||||||
if (d->result)
|
if (d->result)
|
||||||
mysql_free_result(d->result);
|
mysql_free_result(d->result);
|
||||||
|
|
||||||
// must iterate trough leftover result sets from multi-selects or stored procedures
|
// must iterate trough leftover result sets from multi-selects or stored procedures
|
||||||
// if this isn't done subsequent queries will fail with "Commands out of sync"
|
// if this isn't done subsequent queries will fail with "Commands out of sync"
|
||||||
#if MYSQL_VERSION_ID >= 40100
|
#if MYSQL_VERSION_ID >= 40100
|
||||||
while (d->driver && d->driver->d_func()->mysql && mysql_next_result(d->driver->d_func()->mysql) == 0) {
|
while (driver() && d->drv_d_func()->mysql && mysql_next_result(d->drv_d_func()->mysql) == 0) {
|
||||||
MYSQL_RES *res = mysql_store_result(d->driver->d_func()->mysql);
|
MYSQL_RES *res = mysql_store_result(d->drv_d_func()->mysql);
|
||||||
if (res)
|
if (res)
|
||||||
mysql_free_result(res);
|
mysql_free_result(res);
|
||||||
}
|
}
|
||||||
@ -504,7 +504,8 @@ void QMYSQLResult::cleanup()
|
|||||||
|
|
||||||
bool QMYSQLResult::fetch(int i)
|
bool QMYSQLResult::fetch(int i)
|
||||||
{
|
{
|
||||||
if(!d->driver)
|
Q_D(QMYSQLResult);
|
||||||
|
if (!driver())
|
||||||
return false;
|
return false;
|
||||||
if (isForwardOnly()) { // fake a forward seek
|
if (isForwardOnly()) { // fake a forward seek
|
||||||
if (at() < i) {
|
if (at() < i) {
|
||||||
@ -548,7 +549,8 @@ bool QMYSQLResult::fetch(int i)
|
|||||||
|
|
||||||
bool QMYSQLResult::fetchNext()
|
bool QMYSQLResult::fetchNext()
|
||||||
{
|
{
|
||||||
if(!d->driver)
|
Q_D(QMYSQLResult);
|
||||||
|
if (!driver())
|
||||||
return false;
|
return false;
|
||||||
if (d->preparedQuery) {
|
if (d->preparedQuery) {
|
||||||
#if MYSQL_VERSION_ID >= 40108
|
#if MYSQL_VERSION_ID >= 40108
|
||||||
@ -577,7 +579,8 @@ bool QMYSQLResult::fetchNext()
|
|||||||
|
|
||||||
bool QMYSQLResult::fetchLast()
|
bool QMYSQLResult::fetchLast()
|
||||||
{
|
{
|
||||||
if(!d->driver)
|
Q_D(QMYSQLResult);
|
||||||
|
if (!driver())
|
||||||
return false;
|
return false;
|
||||||
if (isForwardOnly()) { // fake this since MySQL can't seek on forward only queries
|
if (isForwardOnly()) { // fake this since MySQL can't seek on forward only queries
|
||||||
bool success = fetchNext(); // did we move at all?
|
bool success = fetchNext(); // did we move at all?
|
||||||
@ -614,13 +617,13 @@ bool QMYSQLResult::fetchFirst()
|
|||||||
|
|
||||||
QVariant QMYSQLResult::data(int field)
|
QVariant QMYSQLResult::data(int field)
|
||||||
{
|
{
|
||||||
|
Q_D(QMYSQLResult);
|
||||||
if (!isSelect() || field >= d->fields.count()) {
|
if (!isSelect() || field >= d->fields.count()) {
|
||||||
qWarning("QMYSQLResult::data: column %d out of range", field);
|
qWarning("QMYSQLResult::data: column %d out of range", field);
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d->driver)
|
if (!driver())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
int fieldLength = 0;
|
int fieldLength = 0;
|
||||||
@ -634,7 +637,7 @@ QVariant QMYSQLResult::data(int field)
|
|||||||
return QVariant(f.type, f.outField);
|
return QVariant(f.type, f.outField);
|
||||||
|
|
||||||
if (f.type != QVariant::ByteArray)
|
if (f.type != QVariant::ByteArray)
|
||||||
val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength);
|
val = toUnicode(d->drv_d_func()->tc, f.outField, f.bufLength);
|
||||||
} else {
|
} else {
|
||||||
if (d->row[field] == NULL) {
|
if (d->row[field] == NULL) {
|
||||||
// NULL value
|
// NULL value
|
||||||
@ -644,7 +647,7 @@ QVariant QMYSQLResult::data(int field)
|
|||||||
fieldLength = mysql_fetch_lengths(d->result)[field];
|
fieldLength = mysql_fetch_lengths(d->result)[field];
|
||||||
|
|
||||||
if (f.type != QVariant::ByteArray)
|
if (f.type != QVariant::ByteArray)
|
||||||
val = toUnicode(d->driver->d_func()->tc, d->row[field], fieldLength);
|
val = toUnicode(d->drv_d_func()->tc, d->row[field], fieldLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (static_cast<int>(f.type)) {
|
switch (static_cast<int>(f.type)) {
|
||||||
@ -712,6 +715,7 @@ QVariant QMYSQLResult::data(int field)
|
|||||||
|
|
||||||
bool QMYSQLResult::isNull(int field)
|
bool QMYSQLResult::isNull(int field)
|
||||||
{
|
{
|
||||||
|
Q_D(const QMYSQLResult);
|
||||||
if (field < 0 || field >= d->fields.count())
|
if (field < 0 || field >= d->fields.count())
|
||||||
return true;
|
return true;
|
||||||
if (d->preparedQuery)
|
if (d->preparedQuery)
|
||||||
@ -722,29 +726,30 @@ bool QMYSQLResult::isNull(int field)
|
|||||||
|
|
||||||
bool QMYSQLResult::reset (const QString& query)
|
bool QMYSQLResult::reset (const QString& query)
|
||||||
{
|
{
|
||||||
if (!driver() || !driver()->isOpen() || driver()->isOpenError() || !d->driver)
|
Q_D(QMYSQLResult);
|
||||||
|
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
d->preparedQuery = false;
|
d->preparedQuery = false;
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query));
|
const QByteArray encQuery(fromUnicode(d->drv_d_func()->tc, query));
|
||||||
if (mysql_real_query(d->driver->d_func()->mysql, encQuery.data(), encQuery.length())) {
|
if (mysql_real_query(d->drv_d_func()->mysql, encQuery.data(), encQuery.length())) {
|
||||||
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute query"),
|
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute query"),
|
||||||
QSqlError::StatementError, d->driver->d_func()));
|
QSqlError::StatementError, d->drv_d_func()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
d->result = mysql_store_result(d->driver->d_func()->mysql);
|
d->result = mysql_store_result(d->drv_d_func()->mysql);
|
||||||
if (!d->result && mysql_field_count(d->driver->d_func()->mysql) > 0) {
|
if (!d->result && mysql_field_count(d->drv_d_func()->mysql) > 0) {
|
||||||
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store result"),
|
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store result"),
|
||||||
QSqlError::StatementError, d->driver->d_func()));
|
QSqlError::StatementError, d->drv_d_func()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int numFields = mysql_field_count(d->driver->d_func()->mysql);
|
int numFields = mysql_field_count(d->drv_d_func()->mysql);
|
||||||
setSelect(numFields != 0);
|
setSelect(numFields != 0);
|
||||||
d->fields.resize(numFields);
|
d->fields.resize(numFields);
|
||||||
d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql);
|
d->rowsAffected = mysql_affected_rows(d->drv_d_func()->mysql);
|
||||||
|
|
||||||
if (isSelect()) {
|
if (isSelect()) {
|
||||||
for(int i = 0; i < numFields; i++) {
|
for(int i = 0; i < numFields; i++) {
|
||||||
@ -759,7 +764,8 @@ bool QMYSQLResult::reset (const QString& query)
|
|||||||
|
|
||||||
int QMYSQLResult::size()
|
int QMYSQLResult::size()
|
||||||
{
|
{
|
||||||
if (d->driver && isSelect())
|
Q_D(const QMYSQLResult);
|
||||||
|
if (driver() && isSelect())
|
||||||
if (d->preparedQuery)
|
if (d->preparedQuery)
|
||||||
#if MYSQL_VERSION_ID >= 40108
|
#if MYSQL_VERSION_ID >= 40108
|
||||||
return mysql_stmt_num_rows(d->stmt);
|
return mysql_stmt_num_rows(d->stmt);
|
||||||
@ -774,12 +780,14 @@ int QMYSQLResult::size()
|
|||||||
|
|
||||||
int QMYSQLResult::numRowsAffected()
|
int QMYSQLResult::numRowsAffected()
|
||||||
{
|
{
|
||||||
|
Q_D(const QMYSQLResult);
|
||||||
return d->rowsAffected;
|
return d->rowsAffected;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QMYSQLResult::lastInsertId() const
|
QVariant QMYSQLResult::lastInsertId() const
|
||||||
{
|
{
|
||||||
if (!isActive() || !d->driver)
|
Q_D(const QMYSQLResult);
|
||||||
|
if (!isActive() || !driver())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (d->preparedQuery) {
|
if (d->preparedQuery) {
|
||||||
@ -789,7 +797,7 @@ QVariant QMYSQLResult::lastInsertId() const
|
|||||||
return QVariant(id);
|
return QVariant(id);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
quint64 id = mysql_insert_id(d->driver->d_func()->mysql);
|
quint64 id = mysql_insert_id(d->drv_d_func()->mysql);
|
||||||
if (id)
|
if (id)
|
||||||
return QVariant(id);
|
return QVariant(id);
|
||||||
}
|
}
|
||||||
@ -798,9 +806,10 @@ QVariant QMYSQLResult::lastInsertId() const
|
|||||||
|
|
||||||
QSqlRecord QMYSQLResult::record() const
|
QSqlRecord QMYSQLResult::record() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QMYSQLResult);
|
||||||
QSqlRecord info;
|
QSqlRecord info;
|
||||||
MYSQL_RES *res;
|
MYSQL_RES *res;
|
||||||
if (!isActive() || !isSelect() || !d->driver)
|
if (!isActive() || !isSelect() || !driver())
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
#if MYSQL_VERSION_ID >= 40108
|
#if MYSQL_VERSION_ID >= 40108
|
||||||
@ -809,11 +818,11 @@ QSqlRecord QMYSQLResult::record() const
|
|||||||
res = d->result;
|
res = d->result;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!mysql_errno(d->driver->d_func()->mysql)) {
|
if (!mysql_errno(d->drv_d_func()->mysql)) {
|
||||||
mysql_field_seek(res, 0);
|
mysql_field_seek(res, 0);
|
||||||
MYSQL_FIELD* field = mysql_fetch_field(res);
|
MYSQL_FIELD* field = mysql_fetch_field(res);
|
||||||
while(field) {
|
while(field) {
|
||||||
info.append(qToField(field, d->driver->d_func()->tc));
|
info.append(qToField(field, d->drv_d_func()->tc));
|
||||||
field = mysql_fetch_field(res);
|
field = mysql_fetch_field(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -823,7 +832,8 @@ QSqlRecord QMYSQLResult::record() const
|
|||||||
|
|
||||||
bool QMYSQLResult::nextResult()
|
bool QMYSQLResult::nextResult()
|
||||||
{
|
{
|
||||||
if(!d->driver)
|
Q_D(QMYSQLResult);
|
||||||
|
if (!driver())
|
||||||
return false;
|
return false;
|
||||||
#if MYSQL_VERSION_ID >= 40100
|
#if MYSQL_VERSION_ID >= 40100
|
||||||
setAt(-1);
|
setAt(-1);
|
||||||
@ -838,26 +848,26 @@ bool QMYSQLResult::nextResult()
|
|||||||
delete[] d->fields[i].outField;
|
delete[] d->fields[i].outField;
|
||||||
d->fields.clear();
|
d->fields.clear();
|
||||||
|
|
||||||
int status = mysql_next_result(d->driver->d_func()->mysql);
|
int status = mysql_next_result(d->drv_d_func()->mysql);
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute next query"),
|
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute next query"),
|
||||||
QSqlError::StatementError, d->driver->d_func()));
|
QSqlError::StatementError, d->drv_d_func()));
|
||||||
return false;
|
return false;
|
||||||
} else if (status == -1) {
|
} else if (status == -1) {
|
||||||
return false; // No more result sets
|
return false; // No more result sets
|
||||||
}
|
}
|
||||||
|
|
||||||
d->result = mysql_store_result(d->driver->d_func()->mysql);
|
d->result = mysql_store_result(d->drv_d_func()->mysql);
|
||||||
int numFields = mysql_field_count(d->driver->d_func()->mysql);
|
int numFields = mysql_field_count(d->drv_d_func()->mysql);
|
||||||
if (!d->result && numFields > 0) {
|
if (!d->result && numFields > 0) {
|
||||||
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store next result"),
|
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store next result"),
|
||||||
QSqlError::StatementError, d->driver->d_func()));
|
QSqlError::StatementError, d->drv_d_func()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSelect(numFields > 0);
|
setSelect(numFields > 0);
|
||||||
d->fields.resize(numFields);
|
d->fields.resize(numFields);
|
||||||
d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql);
|
d->rowsAffected = mysql_affected_rows(d->drv_d_func()->mysql);
|
||||||
|
|
||||||
if (isSelect()) {
|
if (isSelect()) {
|
||||||
for (int i = 0; i < numFields; i++) {
|
for (int i = 0; i < numFields; i++) {
|
||||||
@ -906,11 +916,12 @@ static MYSQL_TIME *toMySqlDate(QDate date, QTime time, QVariant::Type type)
|
|||||||
|
|
||||||
bool QMYSQLResult::prepare(const QString& query)
|
bool QMYSQLResult::prepare(const QString& query)
|
||||||
{
|
{
|
||||||
if(!d->driver)
|
Q_D(QMYSQLResult);
|
||||||
|
if (!driver())
|
||||||
return false;
|
return false;
|
||||||
#if MYSQL_VERSION_ID >= 40108
|
#if MYSQL_VERSION_ID >= 40108
|
||||||
cleanup();
|
cleanup();
|
||||||
if (!d->driver->d_func()->preparedQuerysEnabled)
|
if (!d->drv_d_func()->preparedQuerysEnabled)
|
||||||
return QSqlResult::prepare(query);
|
return QSqlResult::prepare(query);
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
@ -919,14 +930,14 @@ bool QMYSQLResult::prepare(const QString& query)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!d->stmt)
|
if (!d->stmt)
|
||||||
d->stmt = mysql_stmt_init(d->driver->d_func()->mysql);
|
d->stmt = mysql_stmt_init(d->drv_d_func()->mysql);
|
||||||
if (!d->stmt) {
|
if (!d->stmt) {
|
||||||
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"),
|
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"),
|
||||||
QSqlError::StatementError, d->driver->d_func()));
|
QSqlError::StatementError, d->drv_d_func()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query));
|
const QByteArray encQuery(fromUnicode(d->drv_d_func()->tc, query));
|
||||||
r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length());
|
r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length());
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult",
|
setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult",
|
||||||
@ -949,7 +960,8 @@ bool QMYSQLResult::prepare(const QString& query)
|
|||||||
|
|
||||||
bool QMYSQLResult::exec()
|
bool QMYSQLResult::exec()
|
||||||
{
|
{
|
||||||
if (!d->driver)
|
Q_D(QMYSQLResult);
|
||||||
|
if (!driver())
|
||||||
return false;
|
return false;
|
||||||
if (!d->preparedQuery)
|
if (!d->preparedQuery)
|
||||||
return QSqlResult::exec();
|
return QSqlResult::exec();
|
||||||
@ -1046,7 +1058,7 @@ bool QMYSQLResult::exec()
|
|||||||
break;
|
break;
|
||||||
case QVariant::String:
|
case QVariant::String:
|
||||||
default: {
|
default: {
|
||||||
QByteArray ba = fromUnicode(d->driver->d_func()->tc, val.toString());
|
QByteArray ba = fromUnicode(d->drv_d_func()->tc, val.toString());
|
||||||
stringVector.append(ba);
|
stringVector.append(ba);
|
||||||
currBind->buffer_type = MYSQL_TYPE_STRING;
|
currBind->buffer_type = MYSQL_TYPE_STRING;
|
||||||
currBind->buffer = const_cast<char *>(ba.constData());
|
currBind->buffer = const_cast<char *>(ba.constData());
|
||||||
@ -1645,5 +1657,3 @@ bool QMYSQLDriver::isIdentifierEscaped(const QString &identifier, IdentifierType
|
|||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#include "qsql_mysql.moc"
|
|
||||||
|
@ -65,7 +65,7 @@ class QMYSQLDriverPrivate;
|
|||||||
|
|
||||||
class Q_EXPORT_SQLDRIVER_MYSQL QMYSQLDriver : public QSqlDriver
|
class Q_EXPORT_SQLDRIVER_MYSQL QMYSQLDriver : public QSqlDriver
|
||||||
{
|
{
|
||||||
friend class QMYSQLResult;
|
friend class QMYSQLResultPrivate;
|
||||||
Q_DECLARE_PRIVATE(QMYSQLDriver)
|
Q_DECLARE_PRIVATE(QMYSQLDriver)
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -155,16 +155,37 @@ QT_BEGIN_INCLUDE_NAMESPACE
|
|||||||
Q_DECLARE_METATYPE(QOCIRowIdPointer)
|
Q_DECLARE_METATYPE(QOCIRowIdPointer)
|
||||||
QT_END_INCLUDE_NAMESPACE
|
QT_END_INCLUDE_NAMESPACE
|
||||||
|
|
||||||
|
class QOCIDriverPrivate : public QSqlDriverPrivate
|
||||||
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QOCIDriver)
|
||||||
|
|
||||||
|
public:
|
||||||
|
QOCIDriverPrivate();
|
||||||
|
|
||||||
|
OCIEnv *env;
|
||||||
|
OCISvcCtx *svc;
|
||||||
|
OCIServer *srvhp;
|
||||||
|
OCISession *authp;
|
||||||
|
OCIError *err;
|
||||||
|
bool transaction;
|
||||||
|
int serverVersion;
|
||||||
|
int prefetchRows;
|
||||||
|
int prefetchMem;
|
||||||
|
QString user;
|
||||||
|
|
||||||
|
void allocErrorHandle();
|
||||||
|
};
|
||||||
|
|
||||||
class QOCICols;
|
class QOCICols;
|
||||||
struct QOCIResultPrivate;
|
class QOCIResultPrivate;
|
||||||
|
|
||||||
class QOCIResult: public QSqlCachedResult
|
class QOCIResult: public QSqlCachedResult
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QOCIResult)
|
||||||
friend class QOCIDriver;
|
friend class QOCIDriver;
|
||||||
friend struct QOCIResultPrivate;
|
|
||||||
friend class QOCICols;
|
friend class QOCICols;
|
||||||
public:
|
public:
|
||||||
QOCIResult(const QOCIDriver * db, const QOCIDriverPrivate* p);
|
QOCIResult(const QOCIDriver *db);
|
||||||
~QOCIResult();
|
~QOCIResult();
|
||||||
bool prepare(const QString &query) Q_DECL_OVERRIDE;
|
bool prepare(const QString &query) Q_DECL_OVERRIDE;
|
||||||
bool exec() Q_DECL_OVERRIDE;
|
bool exec() Q_DECL_OVERRIDE;
|
||||||
@ -179,18 +200,17 @@ protected:
|
|||||||
QVariant lastInsertId() const Q_DECL_OVERRIDE;
|
QVariant lastInsertId() const Q_DECL_OVERRIDE;
|
||||||
bool execBatch(bool arrayBind = false) Q_DECL_OVERRIDE;
|
bool execBatch(bool arrayBind = false) Q_DECL_OVERRIDE;
|
||||||
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
|
||||||
QOCIResultPrivate *d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QOCIResultPrivate
|
class QOCIResultPrivate: public QSqlCachedResultPrivate
|
||||||
{
|
{
|
||||||
QOCIResultPrivate(QOCIResult *result, const QOCIDriverPrivate *driver);
|
public:
|
||||||
|
Q_DECLARE_PUBLIC(QOCIResult)
|
||||||
|
Q_DECLARE_SQLDRIVER_PRIVATE(QOCIDriver)
|
||||||
|
QOCIResultPrivate(QOCIResult *q, const QOCIDriver *drv);
|
||||||
~QOCIResultPrivate();
|
~QOCIResultPrivate();
|
||||||
|
|
||||||
QOCICols *cols;
|
QOCICols *cols;
|
||||||
QOCIResult *q;
|
|
||||||
OCIEnv *env;
|
OCIEnv *env;
|
||||||
OCIError *err;
|
OCIError *err;
|
||||||
OCISvcCtx *&svc;
|
OCISvcCtx *&svc;
|
||||||
@ -207,9 +227,9 @@ struct QOCIResultPrivate
|
|||||||
void outValues(QVector<QVariant> &values, IndicatorArray &indicators,
|
void outValues(QVector<QVariant> &values, IndicatorArray &indicators,
|
||||||
QList<QByteArray> &tmpStorage);
|
QList<QByteArray> &tmpStorage);
|
||||||
inline bool isOutValue(int i) const
|
inline bool isOutValue(int i) const
|
||||||
{ return q->bindValueType(i) & QSql::Out; }
|
{ Q_Q(const QOCIResult); return q->bindValueType(i) & QSql::Out; }
|
||||||
inline bool isBinaryValue(int i) const
|
inline bool isBinaryValue(int i) const
|
||||||
{ return q->bindValueType(i) & QSql::Binary; }
|
{ Q_Q(const QOCIResult); return q->bindValueType(i) & QSql::Binary; }
|
||||||
|
|
||||||
void setCharset(dvoid* handle, ub4 type) const
|
void setCharset(dvoid* handle, ub4 type) const
|
||||||
{
|
{
|
||||||
@ -485,25 +505,6 @@ void QOCIResultPrivate::outValues(QVector<QVariant> &values, IndicatorArray &ind
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class QOCIDriverPrivate : public QSqlDriverPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QOCIDriverPrivate();
|
|
||||||
|
|
||||||
OCIEnv *env;
|
|
||||||
OCISvcCtx *svc;
|
|
||||||
OCIServer *srvhp;
|
|
||||||
OCISession *authp;
|
|
||||||
OCIError *err;
|
|
||||||
bool transaction;
|
|
||||||
int serverVersion;
|
|
||||||
int prefetchRows;
|
|
||||||
int prefetchMem;
|
|
||||||
QString user;
|
|
||||||
|
|
||||||
void allocErrorHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
QOCIDriverPrivate::QOCIDriverPrivate()
|
QOCIDriverPrivate::QOCIDriverPrivate()
|
||||||
: QSqlDriverPrivate(), env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false),
|
: QSqlDriverPrivate(), env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false),
|
||||||
serverVersion(-1), prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM)
|
serverVersion(-1), prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM)
|
||||||
@ -1221,7 +1222,7 @@ OraFieldInfo QOCICols::qMakeOraField(const QOCIResultPrivate* p, OCIParam* param
|
|||||||
if (r != 0)
|
if (r != 0)
|
||||||
qOraWarning("qMakeOraField:", p->err);
|
qOraWarning("qMakeOraField:", p->err);
|
||||||
|
|
||||||
type = qDecodeOCIType(colType, p->q->numericalPrecisionPolicy());
|
type = qDecodeOCIType(colType, p->q_func()->numericalPrecisionPolicy());
|
||||||
|
|
||||||
if (type == QVariant::Int) {
|
if (type == QVariant::Int) {
|
||||||
if (colLength == 22 && colPrecision == 0 && colScale == 0)
|
if (colLength == 22 && colPrecision == 0 && colScale == 0)
|
||||||
@ -1232,16 +1233,16 @@ OraFieldInfo QOCICols::qMakeOraField(const QOCIResultPrivate* p, OCIParam* param
|
|||||||
|
|
||||||
// bind as double if the precision policy asks for it
|
// bind as double if the precision policy asks for it
|
||||||
if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
|
if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
|
||||||
&& (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)) {
|
&& (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)) {
|
||||||
type = QVariant::Double;
|
type = QVariant::Double;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind as int32 or int64 if the precision policy asks for it
|
// bind as int32 or int64 if the precision policy asks for it
|
||||||
if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
|
if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
|
||||||
|| (colType == SQLT_INT)) {
|
|| (colType == SQLT_INT)) {
|
||||||
if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
|
if (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
|
||||||
type = QVariant::LongLong;
|
type = QVariant::LongLong;
|
||||||
else if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
|
else if (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
|
||||||
type = QVariant::Int;
|
type = QVariant::Int;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1336,7 +1337,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
|
|||||||
|
|
||||||
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
|
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
|
||||||
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
|
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
|
||||||
d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
|
d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
|
||||||
"Unable to bind column for batch execute"),
|
"Unable to bind column for batch execute"),
|
||||||
QSqlError::StatementError, d->err));
|
QSqlError::StatementError, d->err));
|
||||||
return false;
|
return false;
|
||||||
@ -1530,7 +1531,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
|
|||||||
|
|
||||||
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
|
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
|
||||||
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
|
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
|
||||||
d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
|
d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
|
||||||
"Unable to bind column for batch execute"),
|
"Unable to bind column for batch execute"),
|
||||||
QSqlError::StatementError, d->err));
|
QSqlError::StatementError, d->err));
|
||||||
return false;
|
return false;
|
||||||
@ -1545,7 +1546,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
|
|||||||
|
|
||||||
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
|
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
|
||||||
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
|
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
|
||||||
d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
|
d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
|
||||||
"Unable to bind column for batch execute"),
|
"Unable to bind column for batch execute"),
|
||||||
QSqlError::StatementError, d->err));
|
QSqlError::StatementError, d->err));
|
||||||
return false;
|
return false;
|
||||||
@ -1560,7 +1561,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
|
|||||||
|
|
||||||
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
|
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
|
||||||
qOraWarning("QOCIPrivate::execBatch: unable to execute batch statement:", d->err);
|
qOraWarning("QOCIPrivate::execBatch: unable to execute batch statement:", d->err);
|
||||||
d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
|
d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
|
||||||
"Unable to execute batch statement"),
|
"Unable to execute batch statement"),
|
||||||
QSqlError::StatementError, d->err));
|
QSqlError::StatementError, d->err));
|
||||||
return false;
|
return false;
|
||||||
@ -1635,9 +1636,9 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d->q->setSelect(false);
|
d->q_func()->setSelect(false);
|
||||||
d->q->setAt(QSql::BeforeFirstRow);
|
d->q_func()->setAt(QSql::BeforeFirstRow);
|
||||||
d->q->setActive(true);
|
d->q_func()->setActive(true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1752,12 +1753,12 @@ void QOCICols::getValues(QVector<QVariant> &v, int index)
|
|||||||
case QVariant::Double:
|
case QVariant::Double:
|
||||||
case QVariant::Int:
|
case QVariant::Int:
|
||||||
case QVariant::LongLong:
|
case QVariant::LongLong:
|
||||||
if (d->q->numericalPrecisionPolicy() != QSql::HighPrecision) {
|
if (d->q_func()->numericalPrecisionPolicy() != QSql::HighPrecision) {
|
||||||
if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
|
if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
|
||||||
&& (fld.typ == QVariant::Double)) {
|
&& (fld.typ == QVariant::Double)) {
|
||||||
v[index + i] = *reinterpret_cast<double *>(fld.data);
|
v[index + i] = *reinterpret_cast<double *>(fld.data);
|
||||||
break;
|
break;
|
||||||
} else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
|
} else if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
|
||||||
&& (fld.typ == QVariant::LongLong)) {
|
&& (fld.typ == QVariant::LongLong)) {
|
||||||
qint64 qll = 0;
|
qint64 qll = 0;
|
||||||
int r = OCINumberToInt(d->err, reinterpret_cast<OCINumber *>(fld.data), sizeof(qint64),
|
int r = OCINumberToInt(d->err, reinterpret_cast<OCINumber *>(fld.data), sizeof(qint64),
|
||||||
@ -1767,7 +1768,7 @@ void QOCICols::getValues(QVector<QVariant> &v, int index)
|
|||||||
else
|
else
|
||||||
v[index + i] = QVariant();
|
v[index + i] = QVariant();
|
||||||
break;
|
break;
|
||||||
} else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
|
} else if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
|
||||||
&& (fld.typ == QVariant::Int)) {
|
&& (fld.typ == QVariant::Int)) {
|
||||||
v[index + i] = *reinterpret_cast<int *>(fld.data);
|
v[index + i] = *reinterpret_cast<int *>(fld.data);
|
||||||
break;
|
break;
|
||||||
@ -1790,10 +1791,17 @@ void QOCICols::getValues(QVector<QVariant> &v, int index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QOCIResultPrivate::QOCIResultPrivate(QOCIResult *result, const QOCIDriverPrivate *driver)
|
QOCIResultPrivate::QOCIResultPrivate(QOCIResult *q, const QOCIDriver *drv)
|
||||||
: cols(0), q(result), env(driver->env), err(0), svc(const_cast<OCISvcCtx*&>(driver->svc)),
|
: QSqlCachedResultPrivate(q, drv),
|
||||||
sql(0), transaction(driver->transaction), serverVersion(driver->serverVersion),
|
cols(0),
|
||||||
prefetchRows(driver->prefetchRows), prefetchMem(driver->prefetchMem)
|
env(drv_d_func()->env),
|
||||||
|
err(0),
|
||||||
|
svc(const_cast<OCISvcCtx*&>(drv_d_func()->svc)),
|
||||||
|
sql(0),
|
||||||
|
transaction(drv_d_func()->transaction),
|
||||||
|
serverVersion(drv_d_func()->serverVersion),
|
||||||
|
prefetchRows(drv_d_func()->prefetchRows),
|
||||||
|
prefetchMem(drv_d_func()->prefetchMem)
|
||||||
{
|
{
|
||||||
int r = OCIHandleAlloc(env,
|
int r = OCIHandleAlloc(env,
|
||||||
reinterpret_cast<void **>(&err),
|
reinterpret_cast<void **>(&err),
|
||||||
@ -1816,24 +1824,24 @@ QOCIResultPrivate::~QOCIResultPrivate()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
QOCIResult::QOCIResult(const QOCIDriver * db, const QOCIDriverPrivate* p)
|
QOCIResult::QOCIResult(const QOCIDriver *db)
|
||||||
: QSqlCachedResult(db)
|
: QSqlCachedResult(*new QOCIResultPrivate(this, db))
|
||||||
{
|
{
|
||||||
d = new QOCIResultPrivate(this, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QOCIResult::~QOCIResult()
|
QOCIResult::~QOCIResult()
|
||||||
{
|
{
|
||||||
|
Q_D(QOCIResult);
|
||||||
if (d->sql) {
|
if (d->sql) {
|
||||||
int r = OCIHandleFree(d->sql, OCI_HTYPE_STMT);
|
int r = OCIHandleFree(d->sql, OCI_HTYPE_STMT);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
qWarning("~QOCIResult: unable to free statement handle");
|
qWarning("~QOCIResult: unable to free statement handle");
|
||||||
}
|
}
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QOCIResult::handle() const
|
QVariant QOCIResult::handle() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QOCIResult);
|
||||||
return QVariant::fromValue(d->sql);
|
return QVariant::fromValue(d->sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1846,6 +1854,7 @@ bool QOCIResult::reset (const QString& query)
|
|||||||
|
|
||||||
bool QOCIResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
|
bool QOCIResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
|
||||||
{
|
{
|
||||||
|
Q_D(QOCIResult);
|
||||||
if (at() == QSql::AfterLastRow)
|
if (at() == QSql::AfterLastRow)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1905,6 +1914,7 @@ int QOCIResult::size()
|
|||||||
|
|
||||||
int QOCIResult::numRowsAffected()
|
int QOCIResult::numRowsAffected()
|
||||||
{
|
{
|
||||||
|
Q_D(QOCIResult);
|
||||||
int rowCount;
|
int rowCount;
|
||||||
OCIAttrGet(d->sql,
|
OCIAttrGet(d->sql,
|
||||||
OCI_HTYPE_STMT,
|
OCI_HTYPE_STMT,
|
||||||
@ -1917,6 +1927,7 @@ int QOCIResult::numRowsAffected()
|
|||||||
|
|
||||||
bool QOCIResult::prepare(const QString& query)
|
bool QOCIResult::prepare(const QString& query)
|
||||||
{
|
{
|
||||||
|
Q_D(QOCIResult);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
QSqlResult::prepare(query);
|
QSqlResult::prepare(query);
|
||||||
|
|
||||||
@ -1962,6 +1973,7 @@ bool QOCIResult::prepare(const QString& query)
|
|||||||
|
|
||||||
bool QOCIResult::exec()
|
bool QOCIResult::exec()
|
||||||
{
|
{
|
||||||
|
Q_D(QOCIResult);
|
||||||
int r = 0;
|
int r = 0;
|
||||||
ub2 stmtType=0;
|
ub2 stmtType=0;
|
||||||
ub4 iters;
|
ub4 iters;
|
||||||
@ -2043,6 +2055,7 @@ bool QOCIResult::exec()
|
|||||||
|
|
||||||
QSqlRecord QOCIResult::record() const
|
QSqlRecord QOCIResult::record() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QOCIResult);
|
||||||
QSqlRecord inf;
|
QSqlRecord inf;
|
||||||
if (!isActive() || !isSelect() || !d->cols)
|
if (!isActive() || !isSelect() || !d->cols)
|
||||||
return inf;
|
return inf;
|
||||||
@ -2051,6 +2064,7 @@ QSqlRecord QOCIResult::record() const
|
|||||||
|
|
||||||
QVariant QOCIResult::lastInsertId() const
|
QVariant QOCIResult::lastInsertId() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QOCIResult);
|
||||||
if (isActive()) {
|
if (isActive()) {
|
||||||
QOCIRowIdPointer ptr(new QOCIRowId(d->env));
|
QOCIRowIdPointer ptr(new QOCIRowId(d->env));
|
||||||
|
|
||||||
@ -2064,6 +2078,7 @@ QVariant QOCIResult::lastInsertId() const
|
|||||||
|
|
||||||
bool QOCIResult::execBatch(bool arrayBind)
|
bool QOCIResult::execBatch(bool arrayBind)
|
||||||
{
|
{
|
||||||
|
Q_D(QOCIResult);
|
||||||
QOCICols::execBatch(d, boundValues(), arrayBind);
|
QOCICols::execBatch(d, boundValues(), arrayBind);
|
||||||
resetBindCount();
|
resetBindCount();
|
||||||
return lastError().type() == QSqlError::NoError;
|
return lastError().type() == QSqlError::NoError;
|
||||||
@ -2301,8 +2316,7 @@ void QOCIDriver::close()
|
|||||||
|
|
||||||
QSqlResult *QOCIDriver::createResult() const
|
QSqlResult *QOCIDriver::createResult() const
|
||||||
{
|
{
|
||||||
Q_D(const QOCIDriver);
|
return new QOCIResult(this);
|
||||||
return new QOCIResult(this, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QOCIDriver::beginTransaction()
|
bool QOCIDriver::beginTransaction()
|
||||||
|
@ -65,8 +65,9 @@ class Q_EXPORT_SQLDRIVER_OCI QOCIDriver : public QSqlDriver
|
|||||||
{
|
{
|
||||||
Q_DECLARE_PRIVATE(QOCIDriver)
|
Q_DECLARE_PRIVATE(QOCIDriver)
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
friend struct QOCIResultPrivate;
|
friend class QOCICols;
|
||||||
friend class QOCIPrivate;
|
friend class QOCIResultPrivate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QOCIDriver(QObject* parent = 0);
|
explicit QOCIDriver(QObject* parent = 0);
|
||||||
QOCIDriver(OCIEnv* env, OCISvcCtx* ctx, QObject* parent = 0);
|
QOCIDriver(OCIEnv* env, OCISvcCtx* ctx, QObject* parent = 0);
|
||||||
|
@ -107,6 +107,8 @@ inline static QVarLengthArray<SQLTCHAR> toSQLTCHAR(const QString &input)
|
|||||||
|
|
||||||
class QODBCDriverPrivate : public QSqlDriverPrivate
|
class QODBCDriverPrivate : public QSqlDriverPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QODBCDriver)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum DefaultCase{Lower, Mixed, Upper, Sensitive};
|
enum DefaultCase{Lower, Mixed, Upper, Sensitive};
|
||||||
QODBCDriverPrivate()
|
QODBCDriverPrivate()
|
||||||
@ -148,8 +150,10 @@ class QODBCResultPrivate;
|
|||||||
|
|
||||||
class QODBCResult: public QSqlResult
|
class QODBCResult: public QSqlResult
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QODBCResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QODBCResult(const QODBCDriver *db, QODBCDriverPrivate *p);
|
QODBCResult(const QODBCDriver *db);
|
||||||
virtual ~QODBCResult();
|
virtual ~QODBCResult();
|
||||||
|
|
||||||
bool prepare(const QString &query) Q_DECL_OVERRIDE;
|
bool prepare(const QString &query) Q_DECL_OVERRIDE;
|
||||||
@ -174,28 +178,32 @@ protected:
|
|||||||
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
||||||
void detachFromResultSet() Q_DECL_OVERRIDE;
|
void detachFromResultSet() Q_DECL_OVERRIDE;
|
||||||
bool nextResult() Q_DECL_OVERRIDE;
|
bool nextResult() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
|
||||||
QODBCResultPrivate *d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QODBCResultPrivate
|
class QODBCResultPrivate: public QSqlResultPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QODBCResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QODBCResultPrivate(QODBCDriverPrivate *dpp)
|
Q_DECLARE_SQLDRIVER_PRIVATE(QODBCDriver)
|
||||||
: hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false)
|
QODBCResultPrivate(QODBCResult *q, const QODBCDriver *db)
|
||||||
|
: QSqlResultPrivate(q, db),
|
||||||
|
hStmt(0),
|
||||||
|
useSchema(false),
|
||||||
|
hasSQLFetchScroll(true),
|
||||||
|
userForwardOnly(false)
|
||||||
{
|
{
|
||||||
unicode = dpp->unicode;
|
unicode = drv_d_func()->unicode;
|
||||||
useSchema = dpp->useSchema;
|
useSchema = drv_d_func()->useSchema;
|
||||||
disconnectCount = dpp->disconnectCount;
|
disconnectCount = drv_d_func()->disconnectCount;
|
||||||
hasSQLFetchScroll = dpp->hasSQLFetchScroll;
|
hasSQLFetchScroll = drv_d_func()->hasSQLFetchScroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clearValues()
|
inline void clearValues()
|
||||||
{ fieldCache.fill(QVariant()); fieldCacheIdx = 0; }
|
{ fieldCache.fill(QVariant()); fieldCacheIdx = 0; }
|
||||||
|
|
||||||
SQLHANDLE dpEnv() const { return driverPrivate ? driverPrivate->hEnv : 0;}
|
SQLHANDLE dpEnv() const { return drv_d_func() ? drv_d_func()->hEnv : 0;}
|
||||||
SQLHANDLE dpDbc() const { return driverPrivate ? driverPrivate->hDbc : 0;}
|
SQLHANDLE dpDbc() const { return drv_d_func() ? drv_d_func()->hDbc : 0;}
|
||||||
SQLHANDLE hStmt;
|
SQLHANDLE hStmt;
|
||||||
|
|
||||||
bool unicode;
|
bool unicode;
|
||||||
@ -206,23 +214,20 @@ public:
|
|||||||
int fieldCacheIdx;
|
int fieldCacheIdx;
|
||||||
int disconnectCount;
|
int disconnectCount;
|
||||||
bool hasSQLFetchScroll;
|
bool hasSQLFetchScroll;
|
||||||
QODBCDriverPrivate *driverPrivate;
|
|
||||||
bool userForwardOnly;
|
bool userForwardOnly;
|
||||||
|
|
||||||
bool isStmtHandleValid(const QSqlDriver *driver);
|
bool isStmtHandleValid();
|
||||||
void updateStmtHandleState(const QSqlDriver *driver);
|
void updateStmtHandleState();
|
||||||
};
|
};
|
||||||
|
|
||||||
bool QODBCResultPrivate::isStmtHandleValid(const QSqlDriver *driver)
|
bool QODBCResultPrivate::isStmtHandleValid()
|
||||||
{
|
{
|
||||||
const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver);
|
return disconnectCount == drv_d_func()->disconnectCount;
|
||||||
return disconnectCount == odbcdriver->d_func()->disconnectCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QODBCResultPrivate::updateStmtHandleState(const QSqlDriver *driver)
|
void QODBCResultPrivate::updateStmtHandleState()
|
||||||
{
|
{
|
||||||
const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver);
|
disconnectCount = drv_d_func()->disconnectCount;
|
||||||
disconnectCount = odbcdriver->d_func()->disconnectCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode = 0)
|
static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode = 0)
|
||||||
@ -947,26 +952,25 @@ QString QODBCDriverPrivate::adjustCase(const QString &identifier) const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
QODBCResult::QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p)
|
QODBCResult::QODBCResult(const QODBCDriver *db)
|
||||||
: QSqlResult(db)
|
: QSqlResult(*new QODBCResultPrivate(this, db))
|
||||||
{
|
{
|
||||||
d = new QODBCResultPrivate(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QODBCResult::~QODBCResult()
|
QODBCResult::~QODBCResult()
|
||||||
{
|
{
|
||||||
if (d->hStmt && d->isStmtHandleValid(driver()) && driver()->isOpen()) {
|
Q_D(QODBCResult);
|
||||||
|
if (d->hStmt && d->isStmtHandleValid() && driver()->isOpen()) {
|
||||||
SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
|
SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
|
||||||
if (r != SQL_SUCCESS)
|
if (r != SQL_SUCCESS)
|
||||||
qSqlWarning(QLatin1String("QODBCDriver: Unable to free statement handle ")
|
qSqlWarning(QLatin1String("QODBCDriver: Unable to free statement handle ")
|
||||||
+ QString::number(r), d);
|
+ QString::number(r), d);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QODBCResult::reset (const QString& query)
|
bool QODBCResult::reset (const QString& query)
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
d->rInf.clear();
|
d->rInf.clear();
|
||||||
@ -976,7 +980,7 @@ bool QODBCResult::reset (const QString& query)
|
|||||||
// Always reallocate the statement handle - the statement attributes
|
// Always reallocate the statement handle - the statement attributes
|
||||||
// are not reset if SQLFreeStmt() is called which causes some problems.
|
// are not reset if SQLFreeStmt() is called which causes some problems.
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
if (d->hStmt && d->isStmtHandleValid(driver())) {
|
if (d->hStmt && d->isStmtHandleValid()) {
|
||||||
r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
|
r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
|
||||||
if (r != SQL_SUCCESS) {
|
if (r != SQL_SUCCESS) {
|
||||||
qSqlWarning(QLatin1String("QODBCResult::reset: Unable to free statement handle"), d);
|
qSqlWarning(QLatin1String("QODBCResult::reset: Unable to free statement handle"), d);
|
||||||
@ -991,7 +995,7 @@ bool QODBCResult::reset (const QString& query)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->updateStmtHandleState(driver());
|
d->updateStmtHandleState();
|
||||||
|
|
||||||
if (d->userForwardOnly) {
|
if (d->userForwardOnly) {
|
||||||
r = SQLSetStmtAttr(d->hStmt,
|
r = SQLSetStmtAttr(d->hStmt,
|
||||||
@ -1043,6 +1047,7 @@ bool QODBCResult::reset (const QString& query)
|
|||||||
|
|
||||||
bool QODBCResult::fetch(int i)
|
bool QODBCResult::fetch(int i)
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
if (!driver()->isOpen())
|
if (!driver()->isOpen())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1079,6 +1084,7 @@ bool QODBCResult::fetch(int i)
|
|||||||
|
|
||||||
bool QODBCResult::fetchNext()
|
bool QODBCResult::fetchNext()
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
d->clearValues();
|
d->clearValues();
|
||||||
|
|
||||||
@ -1101,6 +1107,7 @@ bool QODBCResult::fetchNext()
|
|||||||
|
|
||||||
bool QODBCResult::fetchFirst()
|
bool QODBCResult::fetchFirst()
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
if (isForwardOnly() && at() != QSql::BeforeFirstRow)
|
if (isForwardOnly() && at() != QSql::BeforeFirstRow)
|
||||||
return false;
|
return false;
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
@ -1123,6 +1130,7 @@ bool QODBCResult::fetchFirst()
|
|||||||
|
|
||||||
bool QODBCResult::fetchPrevious()
|
bool QODBCResult::fetchPrevious()
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
if (isForwardOnly())
|
if (isForwardOnly())
|
||||||
return false;
|
return false;
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
@ -1142,6 +1150,7 @@ bool QODBCResult::fetchPrevious()
|
|||||||
|
|
||||||
bool QODBCResult::fetchLast()
|
bool QODBCResult::fetchLast()
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
d->clearValues();
|
d->clearValues();
|
||||||
|
|
||||||
@ -1181,6 +1190,7 @@ bool QODBCResult::fetchLast()
|
|||||||
|
|
||||||
QVariant QODBCResult::data(int field)
|
QVariant QODBCResult::data(int field)
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
if (field >= d->rInf.count() || field < 0) {
|
if (field >= d->rInf.count() || field < 0) {
|
||||||
qWarning() << "QODBCResult::data: column" << field << "out of range";
|
qWarning() << "QODBCResult::data: column" << field << "out of range";
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@ -1281,6 +1291,7 @@ QVariant QODBCResult::data(int field)
|
|||||||
|
|
||||||
bool QODBCResult::isNull(int field)
|
bool QODBCResult::isNull(int field)
|
||||||
{
|
{
|
||||||
|
Q_D(const QODBCResult);
|
||||||
if (field < 0 || field > d->fieldCache.size())
|
if (field < 0 || field > d->fieldCache.size())
|
||||||
return true;
|
return true;
|
||||||
if (field <= d->fieldCacheIdx) {
|
if (field <= d->fieldCacheIdx) {
|
||||||
@ -1299,6 +1310,7 @@ int QODBCResult::size()
|
|||||||
|
|
||||||
int QODBCResult::numRowsAffected()
|
int QODBCResult::numRowsAffected()
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
SQLLEN affectedRowCount = 0;
|
SQLLEN affectedRowCount = 0;
|
||||||
SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
|
SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
|
||||||
if (r == SQL_SUCCESS)
|
if (r == SQL_SUCCESS)
|
||||||
@ -1310,12 +1322,13 @@ int QODBCResult::numRowsAffected()
|
|||||||
|
|
||||||
bool QODBCResult::prepare(const QString& query)
|
bool QODBCResult::prepare(const QString& query)
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
SQLRETURN r;
|
SQLRETURN r;
|
||||||
|
|
||||||
d->rInf.clear();
|
d->rInf.clear();
|
||||||
if (d->hStmt && d->isStmtHandleValid(driver())) {
|
if (d->hStmt && d->isStmtHandleValid()) {
|
||||||
r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
|
r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
|
||||||
if (r != SQL_SUCCESS) {
|
if (r != SQL_SUCCESS) {
|
||||||
qSqlWarning(QLatin1String("QODBCResult::prepare: Unable to close statement"), d);
|
qSqlWarning(QLatin1String("QODBCResult::prepare: Unable to close statement"), d);
|
||||||
@ -1330,7 +1343,7 @@ bool QODBCResult::prepare(const QString& query)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->updateStmtHandleState(driver());
|
d->updateStmtHandleState();
|
||||||
|
|
||||||
if (d->userForwardOnly) {
|
if (d->userForwardOnly) {
|
||||||
r = SQLSetStmtAttr(d->hStmt,
|
r = SQLSetStmtAttr(d->hStmt,
|
||||||
@ -1364,6 +1377,7 @@ bool QODBCResult::prepare(const QString& query)
|
|||||||
|
|
||||||
bool QODBCResult::exec()
|
bool QODBCResult::exec()
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
d->rInf.clear();
|
d->rInf.clear();
|
||||||
@ -1444,7 +1458,7 @@ bool QODBCResult::exec()
|
|||||||
dt->minute = qdt.time().minute();
|
dt->minute = qdt.time().minute();
|
||||||
dt->second = qdt.time().second();
|
dt->second = qdt.time().second();
|
||||||
|
|
||||||
int precision = d->driverPrivate->datetime_precision - 20; // (20 includes a separating period)
|
int precision = d->drv_d_func()->datetime_precision - 20; // (20 includes a separating period)
|
||||||
if (precision <= 0) {
|
if (precision <= 0) {
|
||||||
dt->fraction = 0;
|
dt->fraction = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -1460,7 +1474,7 @@ bool QODBCResult::exec()
|
|||||||
qParamType[bindValueType(i) & QSql::InOut],
|
qParamType[bindValueType(i) & QSql::InOut],
|
||||||
SQL_C_TIMESTAMP,
|
SQL_C_TIMESTAMP,
|
||||||
SQL_TIMESTAMP,
|
SQL_TIMESTAMP,
|
||||||
d->driverPrivate->datetime_precision,
|
d->drv_d_func()->datetime_precision,
|
||||||
precision,
|
precision,
|
||||||
(void *) dt,
|
(void *) dt,
|
||||||
0,
|
0,
|
||||||
@ -1713,6 +1727,7 @@ bool QODBCResult::exec()
|
|||||||
|
|
||||||
QSqlRecord QODBCResult::record() const
|
QSqlRecord QODBCResult::record() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QODBCResult);
|
||||||
if (!isActive() || !isSelect())
|
if (!isActive() || !isSelect())
|
||||||
return QSqlRecord();
|
return QSqlRecord();
|
||||||
return d->rInf;
|
return d->rInf;
|
||||||
@ -1720,9 +1735,10 @@ QSqlRecord QODBCResult::record() const
|
|||||||
|
|
||||||
QVariant QODBCResult::lastInsertId() const
|
QVariant QODBCResult::lastInsertId() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QODBCResult);
|
||||||
QString sql;
|
QString sql;
|
||||||
|
|
||||||
switch (d->driverPrivate->dbmsType) {
|
switch (driver()->dbmsType()) {
|
||||||
case QSqlDriver::MSSqlServer:
|
case QSqlDriver::MSSqlServer:
|
||||||
case QSqlDriver::Sybase:
|
case QSqlDriver::Sybase:
|
||||||
sql = QLatin1String("SELECT @@IDENTITY;");
|
sql = QLatin1String("SELECT @@IDENTITY;");
|
||||||
@ -1752,11 +1768,13 @@ QVariant QODBCResult::lastInsertId() const
|
|||||||
|
|
||||||
QVariant QODBCResult::handle() const
|
QVariant QODBCResult::handle() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QODBCResult);
|
||||||
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
|
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QODBCResult::nextResult()
|
bool QODBCResult::nextResult()
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
d->rInf.clear();
|
d->rInf.clear();
|
||||||
@ -1801,12 +1819,14 @@ void QODBCResult::virtual_hook(int id, void *data)
|
|||||||
|
|
||||||
void QODBCResult::detachFromResultSet()
|
void QODBCResult::detachFromResultSet()
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
if (d->hStmt)
|
if (d->hStmt)
|
||||||
SQLCloseCursor(d->hStmt);
|
SQLCloseCursor(d->hStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QODBCResult::setForwardOnly(bool forward)
|
void QODBCResult::setForwardOnly(bool forward)
|
||||||
{
|
{
|
||||||
|
Q_D(QODBCResult);
|
||||||
d->userForwardOnly = forward;
|
d->userForwardOnly = forward;
|
||||||
QSqlResult::setForwardOnly(forward);
|
QSqlResult::setForwardOnly(forward);
|
||||||
}
|
}
|
||||||
@ -2221,8 +2241,7 @@ void QODBCDriverPrivate::checkDateTimePrecision()
|
|||||||
|
|
||||||
QSqlResult *QODBCDriver::createResult() const
|
QSqlResult *QODBCDriver::createResult() const
|
||||||
{
|
{
|
||||||
Q_D(const QODBCDriver);
|
return new QODBCResult(this);
|
||||||
return new QODBCResult(this, const_cast<QODBCDriverPrivate*>(d));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QODBCDriver::beginTransaction()
|
bool QODBCDriver::beginTransaction()
|
||||||
|
@ -80,6 +80,8 @@ class Q_EXPORT_SQLDRIVER_ODBC QODBCDriver : public QSqlDriver
|
|||||||
{
|
{
|
||||||
Q_DECLARE_PRIVATE(QODBCDriver)
|
Q_DECLARE_PRIVATE(QODBCDriver)
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
friend class QODBCResultPrivate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QODBCDriver(QObject *parent=0);
|
explicit QODBCDriver(QObject *parent=0);
|
||||||
QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent=0);
|
QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent=0);
|
||||||
@ -112,7 +114,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool endTrans();
|
bool endTrans();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
friend class QODBCResultPrivate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -222,8 +222,9 @@ class QPSQLResultPrivate : public QSqlResultPrivate
|
|||||||
{
|
{
|
||||||
Q_DECLARE_PUBLIC(QPSQLResult)
|
Q_DECLARE_PUBLIC(QPSQLResult)
|
||||||
public:
|
public:
|
||||||
QPSQLResultPrivate()
|
Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver);
|
||||||
: QSqlResultPrivate(),
|
QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv)
|
||||||
|
: QSqlResultPrivate(q, drv),
|
||||||
result(0),
|
result(0),
|
||||||
currentSize(-1),
|
currentSize(-1),
|
||||||
preparedQueriesEnabled(false)
|
preparedQueriesEnabled(false)
|
||||||
@ -231,11 +232,6 @@ public:
|
|||||||
|
|
||||||
QString fieldSerial(int i) const Q_DECL_OVERRIDE { return QLatin1Char('$') + QString::number(i + 1); }
|
QString fieldSerial(int i) const Q_DECL_OVERRIDE { return QLatin1Char('$') + QString::number(i + 1); }
|
||||||
void deallocatePreparedStmt();
|
void deallocatePreparedStmt();
|
||||||
const QPSQLDriverPrivate * privDriver() const
|
|
||||||
{
|
|
||||||
Q_Q(const QPSQLResult);
|
|
||||||
return reinterpret_cast<const QPSQLDriver *>(q->driver())->d_func();
|
|
||||||
}
|
|
||||||
|
|
||||||
PGresult *result;
|
PGresult *result;
|
||||||
int currentSize;
|
int currentSize;
|
||||||
@ -277,7 +273,7 @@ bool QPSQLResultPrivate::processResults()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
|
q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
|
||||||
"Unable to create query"), QSqlError::StatementError, privDriver(), result));
|
"Unable to create query"), QSqlError::StatementError, drv_d_func(), result));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,16 +326,16 @@ static QVariant::Type qDecodePSQLType(int t)
|
|||||||
void QPSQLResultPrivate::deallocatePreparedStmt()
|
void QPSQLResultPrivate::deallocatePreparedStmt()
|
||||||
{
|
{
|
||||||
const QString stmt = QLatin1String("DEALLOCATE ") + preparedStmtId;
|
const QString stmt = QLatin1String("DEALLOCATE ") + preparedStmtId;
|
||||||
PGresult *result = privDriver()->exec(stmt);
|
PGresult *result = drv_d_func()->exec(stmt);
|
||||||
|
|
||||||
if (PQresultStatus(result) != PGRES_COMMAND_OK)
|
if (PQresultStatus(result) != PGRES_COMMAND_OK)
|
||||||
qWarning("Unable to free statement: %s", PQerrorMessage(privDriver()->connection));
|
qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection));
|
||||||
PQclear(result);
|
PQclear(result);
|
||||||
preparedStmtId.clear();
|
preparedStmtId.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPSQLResult::QPSQLResult(const QPSQLDriver* db)
|
QPSQLResult::QPSQLResult(const QPSQLDriver* db)
|
||||||
: QSqlResult(*new QPSQLResultPrivate, db)
|
: QSqlResult(*new QPSQLResultPrivate(this, db))
|
||||||
{
|
{
|
||||||
Q_D(QPSQLResult);
|
Q_D(QPSQLResult);
|
||||||
d->preparedQueriesEnabled = db->hasFeature(QSqlDriver::PreparedQueries);
|
d->preparedQueriesEnabled = db->hasFeature(QSqlDriver::PreparedQueries);
|
||||||
@ -413,7 +409,7 @@ QVariant QPSQLResult::data(int i)
|
|||||||
case QVariant::Bool:
|
case QVariant::Bool:
|
||||||
return QVariant((bool)(val[0] == 't'));
|
return QVariant((bool)(val[0] == 't'));
|
||||||
case QVariant::String:
|
case QVariant::String:
|
||||||
return d->privDriver()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val);
|
return d->drv_d_func()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val);
|
||||||
case QVariant::LongLong:
|
case QVariant::LongLong:
|
||||||
if (val[0] == '-')
|
if (val[0] == '-')
|
||||||
return QString::fromLatin1(val).toLongLong();
|
return QString::fromLatin1(val).toLongLong();
|
||||||
@ -504,7 +500,7 @@ bool QPSQLResult::reset (const QString& query)
|
|||||||
return false;
|
return false;
|
||||||
if (!driver()->isOpen() || driver()->isOpenError())
|
if (!driver()->isOpen() || driver()->isOpenError())
|
||||||
return false;
|
return false;
|
||||||
d->result = d->privDriver()->exec(query);
|
d->result = d->drv_d_func()->exec(query);
|
||||||
return d->processResults();
|
return d->processResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,7 +519,7 @@ int QPSQLResult::numRowsAffected()
|
|||||||
QVariant QPSQLResult::lastInsertId() const
|
QVariant QPSQLResult::lastInsertId() const
|
||||||
{
|
{
|
||||||
Q_D(const QPSQLResult);
|
Q_D(const QPSQLResult);
|
||||||
if (d->privDriver()->pro >= QPSQLDriver::Version81) {
|
if (d->drv_d_func()->pro >= QPSQLDriver::Version81) {
|
||||||
QSqlQuery qry(driver()->createResult());
|
QSqlQuery qry(driver()->createResult());
|
||||||
// Most recent sequence value obtained from nextval
|
// Most recent sequence value obtained from nextval
|
||||||
if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next())
|
if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next())
|
||||||
@ -546,7 +542,7 @@ QSqlRecord QPSQLResult::record() const
|
|||||||
int count = PQnfields(d->result);
|
int count = PQnfields(d->result);
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
QSqlField f;
|
QSqlField f;
|
||||||
if (d->privDriver()->isUtf8)
|
if (d->drv_d_func()->isUtf8)
|
||||||
f.setName(QString::fromUtf8(PQfname(d->result, i)));
|
f.setName(QString::fromUtf8(PQfname(d->result, i)));
|
||||||
else
|
else
|
||||||
f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
|
f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
|
||||||
@ -640,11 +636,11 @@ bool QPSQLResult::prepare(const QString &query)
|
|||||||
const QString stmtId = qMakePreparedStmtId();
|
const QString stmtId = qMakePreparedStmtId();
|
||||||
const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query));
|
const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query));
|
||||||
|
|
||||||
PGresult *result = d->privDriver()->exec(stmt);
|
PGresult *result = d->drv_d_func()->exec(stmt);
|
||||||
|
|
||||||
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
|
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
|
||||||
setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
|
setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
|
||||||
"Unable to prepare statement"), QSqlError::StatementError, d->privDriver(), result));
|
"Unable to prepare statement"), QSqlError::StatementError, d->drv_d_func(), result));
|
||||||
PQclear(result);
|
PQclear(result);
|
||||||
d->preparedStmtId.clear();
|
d->preparedStmtId.clear();
|
||||||
return false;
|
return false;
|
||||||
@ -670,7 +666,7 @@ bool QPSQLResult::exec()
|
|||||||
else
|
else
|
||||||
stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId).arg(params);
|
stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId).arg(params);
|
||||||
|
|
||||||
d->result = d->privDriver()->exec(stmt);
|
d->result = d->drv_d_func()->exec(stmt);
|
||||||
|
|
||||||
return d->processResults();
|
return d->processResults();
|
||||||
}
|
}
|
||||||
|
@ -105,8 +105,9 @@ class QSQLiteResultPrivate;
|
|||||||
|
|
||||||
class QSQLiteResult : public QSqlCachedResult
|
class QSQLiteResult : public QSqlCachedResult
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QSQLiteResult)
|
||||||
friend class QSQLiteDriver;
|
friend class QSQLiteDriver;
|
||||||
friend class QSQLiteResultPrivate;
|
|
||||||
public:
|
public:
|
||||||
explicit QSQLiteResult(const QSQLiteDriver* db);
|
explicit QSQLiteResult(const QSQLiteDriver* db);
|
||||||
~QSQLiteResult();
|
~QSQLiteResult();
|
||||||
@ -123,13 +124,12 @@ protected:
|
|||||||
QSqlRecord record() const Q_DECL_OVERRIDE;
|
QSqlRecord record() const Q_DECL_OVERRIDE;
|
||||||
void detachFromResultSet() Q_DECL_OVERRIDE;
|
void detachFromResultSet() Q_DECL_OVERRIDE;
|
||||||
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
|
||||||
QSQLiteResultPrivate* d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QSQLiteDriverPrivate : public QSqlDriverPrivate
|
class QSQLiteDriverPrivate : public QSqlDriverPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QSQLiteDriver)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; }
|
inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; }
|
||||||
sqlite3 *access;
|
sqlite3 *access;
|
||||||
@ -137,17 +137,19 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class QSQLiteResultPrivate
|
class QSQLiteResultPrivate: public QSqlCachedResultPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QSQLiteResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSQLiteResultPrivate(QSQLiteResult *res);
|
Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver)
|
||||||
|
QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
|
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
|
||||||
// initializes the recordInfo and the cache
|
// initializes the recordInfo and the cache
|
||||||
void initColumns(bool emptyResultset);
|
void initColumns(bool emptyResultset);
|
||||||
void finalize();
|
void finalize();
|
||||||
|
|
||||||
QSQLiteResult* q;
|
|
||||||
sqlite3 *access;
|
sqlite3 *access;
|
||||||
|
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
@ -158,13 +160,17 @@ public:
|
|||||||
QVector<QVariant> firstRow;
|
QVector<QVariant> firstRow;
|
||||||
};
|
};
|
||||||
|
|
||||||
QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult* res) : q(res), access(0),
|
QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv)
|
||||||
stmt(0), skippedStatus(false), skipRow(false)
|
: QSqlCachedResultPrivate(q, drv),
|
||||||
|
stmt(0),
|
||||||
|
skippedStatus(false),
|
||||||
|
skipRow(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSQLiteResultPrivate::cleanup()
|
void QSQLiteResultPrivate::cleanup()
|
||||||
{
|
{
|
||||||
|
Q_Q(QSQLiteResult);
|
||||||
finalize();
|
finalize();
|
||||||
rInf.clear();
|
rInf.clear();
|
||||||
skippedStatus = false;
|
skippedStatus = false;
|
||||||
@ -185,6 +191,7 @@ void QSQLiteResultPrivate::finalize()
|
|||||||
|
|
||||||
void QSQLiteResultPrivate::initColumns(bool emptyResultset)
|
void QSQLiteResultPrivate::initColumns(bool emptyResultset)
|
||||||
{
|
{
|
||||||
|
Q_Q(QSQLiteResult);
|
||||||
int nCols = sqlite3_column_count(stmt);
|
int nCols = sqlite3_column_count(stmt);
|
||||||
if (nCols <= 0)
|
if (nCols <= 0)
|
||||||
return;
|
return;
|
||||||
@ -236,6 +243,7 @@ void QSQLiteResultPrivate::initColumns(bool emptyResultset)
|
|||||||
|
|
||||||
bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
|
bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
|
||||||
{
|
{
|
||||||
|
Q_Q(QSQLiteResult);
|
||||||
int res;
|
int res;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -336,20 +344,18 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
|
|||||||
}
|
}
|
||||||
|
|
||||||
QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db)
|
QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db)
|
||||||
: QSqlCachedResult(db)
|
: QSqlCachedResult(*new QSQLiteResultPrivate(this, db))
|
||||||
{
|
{
|
||||||
d = new QSQLiteResultPrivate(this);
|
Q_D(QSQLiteResult);
|
||||||
d->access = db->d_func()->access;
|
d->access = d->drv_d_func()->access;
|
||||||
const_cast<QSQLiteDriverPrivate*>(db->d_func())->results.append(this);
|
const_cast<QSQLiteDriverPrivate*>(d->drv_d_func())->results.append(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSQLiteResult::~QSQLiteResult()
|
QSQLiteResult::~QSQLiteResult()
|
||||||
{
|
{
|
||||||
const QSqlDriver *sqlDriver = driver();
|
Q_D(QSQLiteResult);
|
||||||
if (sqlDriver)
|
const_cast<QSQLiteDriverPrivate*>(d->drv_d_func())->results.removeOne(this);
|
||||||
const_cast<QSQLiteDriverPrivate*>(qobject_cast<const QSQLiteDriver *>(sqlDriver)->d_func())->results.removeOne(this);
|
|
||||||
d->cleanup();
|
d->cleanup();
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSQLiteResult::virtual_hook(int id, void *data)
|
void QSQLiteResult::virtual_hook(int id, void *data)
|
||||||
@ -366,6 +372,7 @@ bool QSQLiteResult::reset(const QString &query)
|
|||||||
|
|
||||||
bool QSQLiteResult::prepare(const QString &query)
|
bool QSQLiteResult::prepare(const QString &query)
|
||||||
{
|
{
|
||||||
|
Q_D(QSQLiteResult);
|
||||||
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
|
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -399,6 +406,7 @@ bool QSQLiteResult::prepare(const QString &query)
|
|||||||
|
|
||||||
bool QSQLiteResult::exec()
|
bool QSQLiteResult::exec()
|
||||||
{
|
{
|
||||||
|
Q_D(QSQLiteResult);
|
||||||
const QVector<QVariant> values = boundValues();
|
const QVector<QVariant> values = boundValues();
|
||||||
|
|
||||||
d->skippedStatus = false;
|
d->skippedStatus = false;
|
||||||
@ -493,6 +501,7 @@ bool QSQLiteResult::exec()
|
|||||||
|
|
||||||
bool QSQLiteResult::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
|
bool QSQLiteResult::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
|
||||||
{
|
{
|
||||||
|
Q_D(QSQLiteResult);
|
||||||
return d->fetchNext(row, idx, false);
|
return d->fetchNext(row, idx, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,11 +512,13 @@ int QSQLiteResult::size()
|
|||||||
|
|
||||||
int QSQLiteResult::numRowsAffected()
|
int QSQLiteResult::numRowsAffected()
|
||||||
{
|
{
|
||||||
|
Q_D(const QSQLiteResult);
|
||||||
return sqlite3_changes(d->access);
|
return sqlite3_changes(d->access);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QSQLiteResult::lastInsertId() const
|
QVariant QSQLiteResult::lastInsertId() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QSQLiteResult);
|
||||||
if (isActive()) {
|
if (isActive()) {
|
||||||
qint64 id = sqlite3_last_insert_rowid(d->access);
|
qint64 id = sqlite3_last_insert_rowid(d->access);
|
||||||
if (id)
|
if (id)
|
||||||
@ -518,6 +529,7 @@ QVariant QSQLiteResult::lastInsertId() const
|
|||||||
|
|
||||||
QSqlRecord QSQLiteResult::record() const
|
QSqlRecord QSQLiteResult::record() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QSQLiteResult);
|
||||||
if (!isActive() || !isSelect())
|
if (!isActive() || !isSelect())
|
||||||
return QSqlRecord();
|
return QSqlRecord();
|
||||||
return d->rInf;
|
return d->rInf;
|
||||||
@ -525,12 +537,14 @@ QSqlRecord QSQLiteResult::record() const
|
|||||||
|
|
||||||
void QSQLiteResult::detachFromResultSet()
|
void QSQLiteResult::detachFromResultSet()
|
||||||
{
|
{
|
||||||
|
Q_D(QSQLiteResult);
|
||||||
if (d->stmt)
|
if (d->stmt)
|
||||||
sqlite3_reset(d->stmt);
|
sqlite3_reset(d->stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QSQLiteResult::handle() const
|
QVariant QSQLiteResult::handle() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QSQLiteResult);
|
||||||
return QVariant::fromValue(d->stmt);
|
return QVariant::fromValue(d->stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,7 +654,7 @@ void QSQLiteDriver::close()
|
|||||||
Q_D(QSQLiteDriver);
|
Q_D(QSQLiteDriver);
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
foreach (QSQLiteResult *result, d->results) {
|
foreach (QSQLiteResult *result, d->results) {
|
||||||
result->d->finalize();
|
result->d_func()->finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sqlite3_close(d->access) != SQLITE_OK)
|
if (sqlite3_close(d->access) != SQLITE_OK)
|
||||||
|
@ -64,7 +64,7 @@ class Q_EXPORT_SQLDRIVER_SQLITE QSQLiteDriver : public QSqlDriver
|
|||||||
{
|
{
|
||||||
Q_DECLARE_PRIVATE(QSQLiteDriver)
|
Q_DECLARE_PRIVATE(QSQLiteDriver)
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
friend class QSQLiteResult;
|
friend class QSQLiteResultPrivate;
|
||||||
public:
|
public:
|
||||||
explicit QSQLiteDriver(QObject *parent = 0);
|
explicit QSQLiteDriver(QObject *parent = 0);
|
||||||
explicit QSQLiteDriver(sqlite3 *connection, QObject *parent = 0);
|
explicit QSQLiteDriver(sqlite3 *connection, QObject *parent = 0);
|
||||||
|
@ -77,6 +77,8 @@ static QVariant::Type nameToType(const QString& typeName)
|
|||||||
|
|
||||||
class QSQLite2DriverPrivate : public QSqlDriverPrivate
|
class QSQLite2DriverPrivate : public QSqlDriverPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QSQLite2Driver)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSQLite2DriverPrivate();
|
QSQLite2DriverPrivate();
|
||||||
sqlite *access;
|
sqlite *access;
|
||||||
@ -93,8 +95,9 @@ class QSQLite2ResultPrivate;
|
|||||||
|
|
||||||
class QSQLite2Result : public QSqlCachedResult
|
class QSQLite2Result : public QSqlCachedResult
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QSQLite2Result)
|
||||||
friend class QSQLite2Driver;
|
friend class QSQLite2Driver;
|
||||||
friend class QSQLite2ResultPrivate;
|
|
||||||
public:
|
public:
|
||||||
explicit QSQLite2Result(const QSQLite2Driver* db);
|
explicit QSQLite2Result(const QSQLite2Driver* db);
|
||||||
~QSQLite2Result();
|
~QSQLite2Result();
|
||||||
@ -108,15 +111,15 @@ protected:
|
|||||||
QSqlRecord record() const Q_DECL_OVERRIDE;
|
QSqlRecord record() const Q_DECL_OVERRIDE;
|
||||||
void detachFromResultSet() Q_DECL_OVERRIDE;
|
void detachFromResultSet() Q_DECL_OVERRIDE;
|
||||||
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
|
||||||
QSQLite2ResultPrivate* d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QSQLite2ResultPrivate
|
class QSQLite2ResultPrivate: public QSqlCachedResultPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QSQLite2Result)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSQLite2ResultPrivate(QSQLite2Result *res);
|
Q_DECLARE_SQLDRIVER_PRIVATE(QSQLite2Driver);
|
||||||
|
QSQLite2ResultPrivate(QSQLite2Result *q, const QSQLite2Driver *drv);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
|
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
|
||||||
bool isSelect();
|
bool isSelect();
|
||||||
@ -124,7 +127,6 @@ public:
|
|||||||
void init(const char **cnames, int numCols);
|
void init(const char **cnames, int numCols);
|
||||||
void finalize();
|
void finalize();
|
||||||
|
|
||||||
QSQLite2Result* q;
|
|
||||||
sqlite *access;
|
sqlite *access;
|
||||||
|
|
||||||
// and we have too keep our own struct for the data (sqlite works via
|
// and we have too keep our own struct for the data (sqlite works via
|
||||||
@ -141,13 +143,19 @@ public:
|
|||||||
|
|
||||||
static const uint initial_cache_size = 128;
|
static const uint initial_cache_size = 128;
|
||||||
|
|
||||||
QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result* res) : q(res), access(0), currentTail(0),
|
QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result *q, const QSQLite2Driver *drv)
|
||||||
currentMachine(0), skippedStatus(false), skipRow(false), utf8(false)
|
: QSqlCachedResultPrivate(q, drv),
|
||||||
|
currentTail(0),
|
||||||
|
currentMachine(0),
|
||||||
|
skippedStatus(false),
|
||||||
|
skipRow(false),
|
||||||
|
utf8(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSQLite2ResultPrivate::cleanup()
|
void QSQLite2ResultPrivate::cleanup()
|
||||||
{
|
{
|
||||||
|
Q_Q(QSQLite2Result);
|
||||||
finalize();
|
finalize();
|
||||||
rInf.clear();
|
rInf.clear();
|
||||||
currentTail = 0;
|
currentTail = 0;
|
||||||
@ -161,6 +169,7 @@ void QSQLite2ResultPrivate::cleanup()
|
|||||||
|
|
||||||
void QSQLite2ResultPrivate::finalize()
|
void QSQLite2ResultPrivate::finalize()
|
||||||
{
|
{
|
||||||
|
Q_Q(QSQLite2Result);
|
||||||
if (!currentMachine)
|
if (!currentMachine)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -178,6 +187,7 @@ void QSQLite2ResultPrivate::finalize()
|
|||||||
// called on first fetch
|
// called on first fetch
|
||||||
void QSQLite2ResultPrivate::init(const char **cnames, int numCols)
|
void QSQLite2ResultPrivate::init(const char **cnames, int numCols)
|
||||||
{
|
{
|
||||||
|
Q_Q(QSQLite2Result);
|
||||||
if (!cnames)
|
if (!cnames)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -204,6 +214,7 @@ void QSQLite2ResultPrivate::init(const char **cnames, int numCols)
|
|||||||
|
|
||||||
bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
|
bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
|
||||||
{
|
{
|
||||||
|
Q_Q(QSQLite2Result);
|
||||||
// may be caching.
|
// may be caching.
|
||||||
const char **fvals;
|
const char **fvals;
|
||||||
const char **cnames;
|
const char **cnames;
|
||||||
@ -270,17 +281,17 @@ bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
QSQLite2Result::QSQLite2Result(const QSQLite2Driver* db)
|
QSQLite2Result::QSQLite2Result(const QSQLite2Driver* db)
|
||||||
: QSqlCachedResult(db)
|
: QSqlCachedResult(*new QSQLite2ResultPrivate(this, db))
|
||||||
{
|
{
|
||||||
d = new QSQLite2ResultPrivate(this);
|
Q_D(QSQLite2Result);
|
||||||
d->access = db->d_func()->access;
|
d->access = d->drv_d_func()->access;
|
||||||
d->utf8 = db->d_func()->utf8;
|
d->utf8 = d->drv_d_func()->utf8;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSQLite2Result::~QSQLite2Result()
|
QSQLite2Result::~QSQLite2Result()
|
||||||
{
|
{
|
||||||
|
Q_D(QSQLite2Result);
|
||||||
d->cleanup();
|
d->cleanup();
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSQLite2Result::virtual_hook(int id, void *data)
|
void QSQLite2Result::virtual_hook(int id, void *data)
|
||||||
@ -293,6 +304,7 @@ void QSQLite2Result::virtual_hook(int id, void *data)
|
|||||||
*/
|
*/
|
||||||
bool QSQLite2Result::reset (const QString& query)
|
bool QSQLite2Result::reset (const QString& query)
|
||||||
{
|
{
|
||||||
|
Q_D(QSQLite2Result);
|
||||||
// this is where we build a query.
|
// this is where we build a query.
|
||||||
if (!driver())
|
if (!driver())
|
||||||
return false;
|
return false;
|
||||||
@ -336,6 +348,7 @@ bool QSQLite2Result::reset (const QString& query)
|
|||||||
|
|
||||||
bool QSQLite2Result::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
|
bool QSQLite2Result::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
|
||||||
{
|
{
|
||||||
|
Q_D(QSQLite2Result);
|
||||||
return d->fetchNext(row, idx, false);
|
return d->fetchNext(row, idx, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,11 +359,13 @@ int QSQLite2Result::size()
|
|||||||
|
|
||||||
int QSQLite2Result::numRowsAffected()
|
int QSQLite2Result::numRowsAffected()
|
||||||
{
|
{
|
||||||
|
Q_D(const QSQLite2Result);
|
||||||
return sqlite_changes(d->access);
|
return sqlite_changes(d->access);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlRecord QSQLite2Result::record() const
|
QSqlRecord QSQLite2Result::record() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QSQLite2Result);
|
||||||
if (!isActive() || !isSelect())
|
if (!isActive() || !isSelect())
|
||||||
return QSqlRecord();
|
return QSqlRecord();
|
||||||
return d->rInf;
|
return d->rInf;
|
||||||
@ -358,11 +373,13 @@ QSqlRecord QSQLite2Result::record() const
|
|||||||
|
|
||||||
void QSQLite2Result::detachFromResultSet()
|
void QSQLite2Result::detachFromResultSet()
|
||||||
{
|
{
|
||||||
|
Q_D(QSQLite2Result);
|
||||||
d->finalize();
|
d->finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant QSQLite2Result::handle() const
|
QVariant QSQLite2Result::handle() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QSQLite2Result);
|
||||||
return QVariant::fromValue(d->currentMachine);
|
return QVariant::fromValue(d->currentMachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class QSQLite2DriverPrivate;
|
|||||||
|
|
||||||
class Q_EXPORT_SQLDRIVER_SQLITE2 QSQLite2Driver : public QSqlDriver
|
class Q_EXPORT_SQLDRIVER_SQLITE2 QSQLite2Driver : public QSqlDriver
|
||||||
{
|
{
|
||||||
friend class QSQLite2Result;
|
friend class QSQLite2ResultPrivate;
|
||||||
Q_DECLARE_PRIVATE(QSQLite2Driver)
|
Q_DECLARE_PRIVATE(QSQLite2Driver)
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -131,6 +131,8 @@ QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, int errNo =
|
|||||||
|
|
||||||
class QTDSDriverPrivate : public QSqlDriverPrivate
|
class QTDSDriverPrivate : public QSqlDriverPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QTDSDriver)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QTDSDriverPrivate() : QSqlDriverPrivate(), login(0), initialized(false) { dbmsType = QSqlDriver::Sybase; }
|
QTDSDriverPrivate() : QSqlDriverPrivate(), login(0), initialized(false) { dbmsType = QSqlDriver::Sybase; }
|
||||||
LOGINREC* login; // login information
|
LOGINREC* login; // login information
|
||||||
@ -150,6 +152,8 @@ class QTDSResultPrivate;
|
|||||||
|
|
||||||
class QTDSResult : public QSqlCachedResult
|
class QTDSResult : public QSqlCachedResult
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QTDSResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QTDSResult(const QTDSDriver* db);
|
explicit QTDSResult(const QTDSDriver* db);
|
||||||
~QTDSResult();
|
~QTDSResult();
|
||||||
@ -162,15 +166,18 @@ protected:
|
|||||||
int numRowsAffected() Q_DECL_OVERRIDE;
|
int numRowsAffected() Q_DECL_OVERRIDE;
|
||||||
bool gotoNext(QSqlCachedResult::ValueCache &values, int index) Q_DECL_OVERRIDE;
|
bool gotoNext(QSqlCachedResult::ValueCache &values, int index) Q_DECL_OVERRIDE;
|
||||||
QSqlRecord record() const Q_DECL_OVERRIDE;
|
QSqlRecord record() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
|
||||||
QTDSResultPrivate* d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QTDSResultPrivate
|
class QTDSResultPrivate: public QSqlCachedResultPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QTDSResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QTDSResultPrivate():login(0), dbproc(0) {}
|
Q_DECLARE_SQLDRIVER_PRIVATE(QTDSDriver)
|
||||||
|
QTDSResultPrivate(QTDSResult *q, const QTDSDriver *drv)
|
||||||
|
: QSqlCachedResultPrivate(q, drv),
|
||||||
|
login(0),
|
||||||
|
dbproc(0) {}
|
||||||
LOGINREC* login; // login information
|
LOGINREC* login; // login information
|
||||||
DBPROCESS* dbproc; // connection from app to server
|
DBPROCESS* dbproc; // connection from app to server
|
||||||
QSqlError lastError;
|
QSqlError lastError;
|
||||||
@ -316,15 +323,15 @@ QVariant::Type qFieldType(QTDSResultPrivate* d, int i)
|
|||||||
|
|
||||||
|
|
||||||
QTDSResult::QTDSResult(const QTDSDriver* db)
|
QTDSResult::QTDSResult(const QTDSDriver* db)
|
||||||
: QSqlCachedResult(db)
|
: QSqlCachedResult(*new QTDSResultPrivate(this, db))
|
||||||
{
|
{
|
||||||
d = new QTDSResultPrivate();
|
Q_D(QTDSResult);
|
||||||
d->login = db->d_func()->login;
|
d->login = d->drv_d_func()->login;
|
||||||
|
|
||||||
d->dbproc = dbopen(d->login, const_cast<char*>(db->d_func()->hostName.toLatin1().constData()));
|
d->dbproc = dbopen(d->login, const_cast<char*>(d->drv_d_func()->hostName.toLatin1().constData()));
|
||||||
if (!d->dbproc)
|
if (!d->dbproc)
|
||||||
return;
|
return;
|
||||||
if (dbuse(d->dbproc, const_cast<char*>(db->d_func()->db.toLatin1().constData())) == FAIL)
|
if (dbuse(d->dbproc, const_cast<char*>(d->drv_d_func()->db.toLatin1().constData())) == FAIL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// insert d in error handler dict
|
// insert d in error handler dict
|
||||||
@ -335,15 +342,16 @@ QTDSResult::QTDSResult(const QTDSDriver* db)
|
|||||||
|
|
||||||
QTDSResult::~QTDSResult()
|
QTDSResult::~QTDSResult()
|
||||||
{
|
{
|
||||||
|
Q_D(QTDSResult);
|
||||||
cleanup();
|
cleanup();
|
||||||
if (d->dbproc)
|
if (d->dbproc)
|
||||||
dbclose(d->dbproc);
|
dbclose(d->dbproc);
|
||||||
errs()->remove(d->dbproc);
|
errs()->remove(d->dbproc);
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTDSResult::cleanup()
|
void QTDSResult::cleanup()
|
||||||
{
|
{
|
||||||
|
Q_D(QTDSResult);
|
||||||
d->clearErrorMsgs();
|
d->clearErrorMsgs();
|
||||||
d->rec.clear();
|
d->rec.clear();
|
||||||
for (int i = 0; i < d->buffer.size(); ++i)
|
for (int i = 0; i < d->buffer.size(); ++i)
|
||||||
@ -358,6 +366,7 @@ void QTDSResult::cleanup()
|
|||||||
|
|
||||||
QVariant QTDSResult::handle() const
|
QVariant QTDSResult::handle() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QTDSResult);
|
||||||
return QVariant(qRegisterMetaType<DBPROCESS *>("DBPROCESS*"), &d->dbproc);
|
return QVariant(qRegisterMetaType<DBPROCESS *>("DBPROCESS*"), &d->dbproc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,6 +377,7 @@ static inline bool qIsNull(const QTDSColumnData &p)
|
|||||||
|
|
||||||
bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
|
bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
|
||||||
{
|
{
|
||||||
|
Q_D(QTDSResult);
|
||||||
STATUS stat = dbnextrow(d->dbproc);
|
STATUS stat = dbnextrow(d->dbproc);
|
||||||
if (stat == NO_MORE_ROWS) {
|
if (stat == NO_MORE_ROWS) {
|
||||||
setAt(QSql::AfterLastRow);
|
setAt(QSql::AfterLastRow);
|
||||||
@ -427,6 +437,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
|
|||||||
|
|
||||||
bool QTDSResult::reset (const QString& query)
|
bool QTDSResult::reset (const QString& query)
|
||||||
{
|
{
|
||||||
|
Q_D(QTDSResult);
|
||||||
cleanup();
|
cleanup();
|
||||||
if (!driver() || !driver()-> isOpen() || driver()->isOpenError())
|
if (!driver() || !driver()-> isOpen() || driver()->isOpenError())
|
||||||
return false;
|
return false;
|
||||||
@ -515,6 +526,7 @@ int QTDSResult::size()
|
|||||||
|
|
||||||
int QTDSResult::numRowsAffected()
|
int QTDSResult::numRowsAffected()
|
||||||
{
|
{
|
||||||
|
Q_D(const QTDSResult);
|
||||||
#ifdef DBNTWIN32
|
#ifdef DBNTWIN32
|
||||||
if (dbiscount(d->dbproc)) {
|
if (dbiscount(d->dbproc)) {
|
||||||
return DBCOUNT(d->dbproc);
|
return DBCOUNT(d->dbproc);
|
||||||
@ -527,6 +539,7 @@ int QTDSResult::numRowsAffected()
|
|||||||
|
|
||||||
QSqlRecord QTDSResult::record() const
|
QSqlRecord QTDSResult::record() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QTDSResult);
|
||||||
return d->rec;
|
return d->rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class Q_EXPORT_SQLDRIVER_TDS QTDSDriver : public QSqlDriver
|
|||||||
{
|
{
|
||||||
Q_DECLARE_PRIVATE(QTDSDriver)
|
Q_DECLARE_PRIVATE(QTDSDriver)
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
friend class QTDSResult;
|
friend class QTDSResultPrivate;
|
||||||
public:
|
public:
|
||||||
explicit QTDSDriver(QObject* parent = 0);
|
explicit QTDSDriver(QObject* parent = 0);
|
||||||
QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent = 0);
|
QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent = 0);
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <qvariant.h>
|
#include <qvariant.h>
|
||||||
#include <qdatetime.h>
|
#include <qdatetime.h>
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
#include <QtSql/private/qsqldriver_p.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -53,8 +54,12 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
static const uint initial_cache_size = 128;
|
static const uint initial_cache_size = 128;
|
||||||
|
|
||||||
QSqlCachedResultPrivate::QSqlCachedResultPrivate():
|
QSqlCachedResultPrivate::QSqlCachedResultPrivate(QSqlCachedResult *q, const QSqlDriver *drv)
|
||||||
rowCacheEnd(0), colCount(0), forwardOnly(false), atEnd(false)
|
: QSqlResultPrivate(q, drv),
|
||||||
|
rowCacheEnd(0),
|
||||||
|
colCount(0),
|
||||||
|
forwardOnly(false),
|
||||||
|
atEnd(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,23 +121,24 @@ inline int QSqlCachedResultPrivate::cacheCount() const
|
|||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
QSqlCachedResult::QSqlCachedResult(const QSqlDriver * db): QSqlResult (db)
|
QSqlCachedResult::QSqlCachedResult(QSqlCachedResultPrivate &d)
|
||||||
|
: QSqlResult(d)
|
||||||
{
|
{
|
||||||
d = new QSqlCachedResultPrivate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlCachedResult::~QSqlCachedResult()
|
QSqlCachedResult::~QSqlCachedResult()
|
||||||
{
|
{
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSqlCachedResult::init(int colCount)
|
void QSqlCachedResult::init(int colCount)
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
d->init(colCount, isForwardOnly());
|
d->init(colCount, isForwardOnly());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QSqlCachedResult::fetch(int i)
|
bool QSqlCachedResult::fetch(int i)
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
if ((!isActive()) || (i < 0))
|
if ((!isActive()) || (i < 0))
|
||||||
return false;
|
return false;
|
||||||
if (at() == i)
|
if (at() == i)
|
||||||
@ -171,6 +177,7 @@ bool QSqlCachedResult::fetch(int i)
|
|||||||
|
|
||||||
bool QSqlCachedResult::fetchNext()
|
bool QSqlCachedResult::fetchNext()
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
if (d->canSeek(at() + 1)) {
|
if (d->canSeek(at() + 1)) {
|
||||||
setAt(at() + 1);
|
setAt(at() + 1);
|
||||||
return true;
|
return true;
|
||||||
@ -185,6 +192,7 @@ bool QSqlCachedResult::fetchPrevious()
|
|||||||
|
|
||||||
bool QSqlCachedResult::fetchFirst()
|
bool QSqlCachedResult::fetchFirst()
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
if (d->forwardOnly && at() != QSql::BeforeFirstRow) {
|
if (d->forwardOnly && at() != QSql::BeforeFirstRow) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -197,6 +205,7 @@ bool QSqlCachedResult::fetchFirst()
|
|||||||
|
|
||||||
bool QSqlCachedResult::fetchLast()
|
bool QSqlCachedResult::fetchLast()
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
if (d->atEnd) {
|
if (d->atEnd) {
|
||||||
if (d->forwardOnly)
|
if (d->forwardOnly)
|
||||||
return false;
|
return false;
|
||||||
@ -217,6 +226,7 @@ bool QSqlCachedResult::fetchLast()
|
|||||||
|
|
||||||
QVariant QSqlCachedResult::data(int i)
|
QVariant QSqlCachedResult::data(int i)
|
||||||
{
|
{
|
||||||
|
Q_D(const QSqlCachedResult);
|
||||||
int idx = d->forwardOnly ? i : at() * d->colCount + i;
|
int idx = d->forwardOnly ? i : at() * d->colCount + i;
|
||||||
if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
|
if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@ -226,6 +236,7 @@ QVariant QSqlCachedResult::data(int i)
|
|||||||
|
|
||||||
bool QSqlCachedResult::isNull(int i)
|
bool QSqlCachedResult::isNull(int i)
|
||||||
{
|
{
|
||||||
|
Q_D(const QSqlCachedResult);
|
||||||
int idx = d->forwardOnly ? i : at() * d->colCount + i;
|
int idx = d->forwardOnly ? i : at() * d->colCount + i;
|
||||||
if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
|
if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
|
||||||
return true;
|
return true;
|
||||||
@ -235,6 +246,7 @@ bool QSqlCachedResult::isNull(int i)
|
|||||||
|
|
||||||
void QSqlCachedResult::cleanup()
|
void QSqlCachedResult::cleanup()
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
setActive(false);
|
setActive(false);
|
||||||
d->cleanup();
|
d->cleanup();
|
||||||
@ -242,6 +254,7 @@ void QSqlCachedResult::cleanup()
|
|||||||
|
|
||||||
void QSqlCachedResult::clearValues()
|
void QSqlCachedResult::clearValues()
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
setAt(QSql::BeforeFirstRow);
|
setAt(QSql::BeforeFirstRow);
|
||||||
d->rowCacheEnd = 0;
|
d->rowCacheEnd = 0;
|
||||||
d->atEnd = false;
|
d->atEnd = false;
|
||||||
@ -249,6 +262,7 @@ void QSqlCachedResult::clearValues()
|
|||||||
|
|
||||||
bool QSqlCachedResult::cacheNext()
|
bool QSqlCachedResult::cacheNext()
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
if (d->atEnd)
|
if (d->atEnd)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -268,11 +282,13 @@ bool QSqlCachedResult::cacheNext()
|
|||||||
|
|
||||||
int QSqlCachedResult::colCount() const
|
int QSqlCachedResult::colCount() const
|
||||||
{
|
{
|
||||||
|
Q_D(const QSqlCachedResult);
|
||||||
return d->colCount;
|
return d->colCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlCachedResult::ValueCache &QSqlCachedResult::cache()
|
QSqlCachedResult::ValueCache &QSqlCachedResult::cache()
|
||||||
{
|
{
|
||||||
|
Q_D(QSqlCachedResult);
|
||||||
return d->cache;
|
return d->cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "QtSql/qsqlresult.h"
|
#include "QtSql/qsqlresult.h"
|
||||||
|
#include "QtSql/private/qsqlresult_p.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -56,13 +57,15 @@ class QSqlCachedResultPrivate;
|
|||||||
|
|
||||||
class Q_SQL_EXPORT QSqlCachedResult: public QSqlResult
|
class Q_SQL_EXPORT QSqlCachedResult: public QSqlResult
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PRIVATE(QSqlCachedResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~QSqlCachedResult();
|
virtual ~QSqlCachedResult();
|
||||||
|
|
||||||
typedef QVector<QVariant> ValueCache;
|
typedef QVector<QVariant> ValueCache;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSqlCachedResult(const QSqlDriver * db);
|
QSqlCachedResult(QSqlCachedResultPrivate &d);
|
||||||
|
|
||||||
void init(int colCount);
|
void init(int colCount);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
@ -86,13 +89,14 @@ protected:
|
|||||||
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy) Q_DECL_OVERRIDE;
|
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy) Q_DECL_OVERRIDE;
|
||||||
private:
|
private:
|
||||||
bool cacheNext();
|
bool cacheNext();
|
||||||
QSqlCachedResultPrivate *d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QSqlCachedResultPrivate
|
class Q_SQL_EXPORT QSqlCachedResultPrivate: public QSqlResultPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QSqlCachedResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSqlCachedResultPrivate();
|
QSqlCachedResultPrivate(QSqlCachedResult *q, const QSqlDriver *drv);
|
||||||
bool canSeek(int i) const;
|
bool canSeek(int i) const;
|
||||||
inline int cacheCount() const;
|
inline int cacheCount() const;
|
||||||
void init(int count, bool fo);
|
void init(int count, bool fo);
|
||||||
|
@ -87,7 +87,7 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const
|
|||||||
result.reserve(n * 5 / 4);
|
result.reserve(n * 5 / 4);
|
||||||
QChar closingQuote;
|
QChar closingQuote;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriver::PostgreSQL);
|
bool ignoreBraces = (sqldriver->dbmsType() == QSqlDriver::PostgreSQL);
|
||||||
|
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
QChar ch = query.at(i);
|
QChar ch = query.at(i);
|
||||||
@ -128,7 +128,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
|
|||||||
QChar closingQuote;
|
QChar closingQuote;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriver::PostgreSQL);
|
bool ignoreBraces = (sqldriver->dbmsType() == QSqlDriver::PostgreSQL);
|
||||||
|
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
QChar ch = query.at(i);
|
QChar ch = query.at(i);
|
||||||
@ -218,22 +218,18 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
|
|||||||
|
|
||||||
QSqlResult::QSqlResult(const QSqlDriver *db)
|
QSqlResult::QSqlResult(const QSqlDriver *db)
|
||||||
{
|
{
|
||||||
d_ptr = new QSqlResultPrivate;
|
d_ptr = new QSqlResultPrivate(this, db);
|
||||||
Q_D(QSqlResult);
|
Q_D(QSqlResult);
|
||||||
d->q_ptr = this;
|
|
||||||
d->sqldriver = db;
|
|
||||||
if (d->sqldriver)
|
if (d->sqldriver)
|
||||||
setNumericalPrecisionPolicy(d->sqldriver->numericalPrecisionPolicy());
|
setNumericalPrecisionPolicy(d->sqldriver->numericalPrecisionPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \internal
|
/*! \internal
|
||||||
*/
|
*/
|
||||||
QSqlResult::QSqlResult(QSqlResultPrivate &dd, const QSqlDriver *db)
|
QSqlResult::QSqlResult(QSqlResultPrivate &dd)
|
||||||
|
: d_ptr(&dd)
|
||||||
{
|
{
|
||||||
d_ptr = ⅆ
|
|
||||||
Q_D(QSqlResult);
|
Q_D(QSqlResult);
|
||||||
d->q_ptr = this;
|
|
||||||
d->sqldriver = db;
|
|
||||||
if (d->sqldriver)
|
if (d->sqldriver)
|
||||||
setNumericalPrecisionPolicy(d->sqldriver->numericalPrecisionPolicy());
|
setNumericalPrecisionPolicy(d->sqldriver->numericalPrecisionPolicy());
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
explicit QSqlResult(const QSqlDriver * db);
|
explicit QSqlResult(const QSqlDriver * db);
|
||||||
QSqlResult(QSqlResultPrivate &dd, const QSqlDriver *db);
|
QSqlResult(QSqlResultPrivate &dd);
|
||||||
int at() const;
|
int at() const;
|
||||||
QString lastQuery() const;
|
QString lastQuery() const;
|
||||||
QSqlError lastError() const;
|
QSqlError lastError() const;
|
||||||
|
@ -48,9 +48,15 @@
|
|||||||
#include <QtCore/qpointer.h>
|
#include <QtCore/qpointer.h>
|
||||||
#include "qsqlerror.h"
|
#include "qsqlerror.h"
|
||||||
#include "qsqlresult.h"
|
#include "qsqlresult.h"
|
||||||
|
#include "qsqldriver.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
// convenience method Q*ResultPrivate::drv_d_func() returns pointer to private driver. Compare to Q_DECLARE_PRIVATE in qglobal.h.
|
||||||
|
#define Q_DECLARE_SQLDRIVER_PRIVATE(Class) \
|
||||||
|
inline const Class##Private* drv_d_func() const { return !sqldriver ? nullptr : reinterpret_cast<const Class *>(static_cast<const QSqlDriver*>(sqldriver))->d_func(); } \
|
||||||
|
inline Class##Private* drv_d_func() { return !sqldriver ? nullptr : reinterpret_cast<Class *>(static_cast<QSqlDriver*>(sqldriver))->d_func(); }
|
||||||
|
|
||||||
struct QHolder {
|
struct QHolder {
|
||||||
QHolder(const QString &hldr = QString(), int index = -1): holderName(hldr), holderPos(index) { }
|
QHolder(const QString &hldr = QString(), int index = -1): holderName(hldr), holderPos(index) { }
|
||||||
bool operator==(const QHolder &h) const { return h.holderPos == holderPos && h.holderName == holderName; }
|
bool operator==(const QHolder &h) const { return h.holderPos == holderPos && h.holderName == holderName; }
|
||||||
@ -59,14 +65,14 @@ struct QHolder {
|
|||||||
int holderPos;
|
int holderPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QSqlDriver;
|
|
||||||
|
|
||||||
class Q_SQL_EXPORT QSqlResultPrivate
|
class Q_SQL_EXPORT QSqlResultPrivate
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QSqlResult)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSqlResultPrivate()
|
QSqlResultPrivate(QSqlResult *q, const QSqlDriver *drv)
|
||||||
: q_ptr(0),
|
: q_ptr(q),
|
||||||
|
sqldriver(const_cast<QSqlDriver*>(drv)),
|
||||||
idx(QSql::BeforeFirstRow),
|
idx(QSql::BeforeFirstRow),
|
||||||
active(false),
|
active(false),
|
||||||
isSel(false),
|
isSel(false),
|
||||||
@ -107,7 +113,7 @@ public:
|
|||||||
QString holderAt(int index) const;
|
QString holderAt(int index) const;
|
||||||
|
|
||||||
QSqlResult *q_ptr;
|
QSqlResult *q_ptr;
|
||||||
QPointer<const QSqlDriver> sqldriver;
|
QPointer<QSqlDriver> sqldriver;
|
||||||
int idx;
|
int idx;
|
||||||
QString sql;
|
QString sql;
|
||||||
bool active;
|
bool active;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user