📄 qsql_mysql.cpp
字号:
d->result = NULL; d->row = NULL; setAt(-1); setActive(false); d->preparedQuerys = d->preparedQuerysEnabled;}bool QMYSQLResult::fetch(int i){ if (isForwardOnly()) { // fake a forward seek if (at() < i) { int x = i - at(); while (--x && fetchNext()); return fetchNext(); } else { return false; } } if (at() == i) return true; if (d->preparedQuerys) {#if MYSQL_VERSION_ID >= 40108 mysql_stmt_data_seek(d->stmt, i); if (mysql_stmt_fetch(d->stmt)) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to fetch data"), QSqlError::StatementError, d->stmt)); return false; }#else return false;#endif } else { mysql_data_seek(d->result, i); d->row = mysql_fetch_row(d->result); if (!d->row) return false; } setAt(i); return true;}bool QMYSQLResult::fetchNext(){ if (d->preparedQuerys) {#if MYSQL_VERSION_ID >= 40108 if (mysql_stmt_fetch(d->stmt)) return false;#else return false;#endif } else { d->row = mysql_fetch_row(d->result); if (!d->row) return false; } setAt(at() + 1); return true;}bool QMYSQLResult::fetchLast(){ if (isForwardOnly()) { // fake this since MySQL can't seek on forward only queries bool success = fetchNext(); // did we move at all? while (fetchNext()); return success; } my_ulonglong numRows; if (d->preparedQuerys) {#if MYSQL_VERSION_ID >= 40108 numRows = mysql_stmt_num_rows(d->stmt);#else numRows = 0;#endif } else { numRows = mysql_num_rows(d->result); } if (at() == int(numRows)) return true; if (!numRows) return false; return fetch(numRows - 1);}bool QMYSQLResult::fetchFirst(){ if (at() == 0) return true; if (isForwardOnly()) return (at() == QSql::BeforeFirstRow) ? fetchNext() : false; return fetch(0);}QVariant QMYSQLResult::data(int field){ if (!isSelect() || field >= d->fields.count()) { qWarning("QMYSQLResult::data: column %d out of range", field); return QVariant(); } int fieldLength = 0; const QMYSQLResultPrivate::QMyField &f = d->fields.at(field); QString val; if (d->preparedQuerys) { if (f.nullIndicator) return QVariant(f.type); if (f.type != QVariant::ByteArray) val = toUnicode(d->tc, f.outField, f.bufLength); } else { if (d->row[field] == NULL) { // NULL value return QVariant(f.type); } fieldLength = mysql_fetch_lengths(d->result)[field]; if (f.type != QVariant::ByteArray) val = toUnicode(d->tc, d->row[field], fieldLength); } switch(f.type) { case QVariant::LongLong: return QVariant(val.toLongLong()); case QVariant::ULongLong: return QVariant(val.toULongLong()); case QVariant::Int: return QVariant(val.toInt()); case QVariant::UInt: return QVariant(val.toUInt()); case QVariant::Double: return QVariant(val.toDouble()); case QVariant::Date: return qDateFromString(val); case QVariant::Time: return qTimeFromString(val); case QVariant::DateTime: return qDateTimeFromString(val); case QVariant::ByteArray: { QByteArray ba; if (d->preparedQuerys) { ba = QByteArray(f.outField, f.bufLength); } else { ba = QByteArray(d->row[field], fieldLength); } return QVariant(ba); } default: case QVariant::String: return QVariant(val); } qWarning("QMYSQLResult::data: unknown data type"); return QVariant();}bool QMYSQLResult::isNull(int field){ if (d->preparedQuerys) return d->fields.at(field).nullIndicator; else return d->row[field] == NULL;}bool QMYSQLResult::reset (const QString& query){ if (!driver() || !driver()->isOpen() || driver()->isOpenError()) return false; cleanup(); d->preparedQuerys = false; const QByteArray encQuery(fromUnicode(d->tc, query)); if (mysql_real_query(d->mysql, encQuery.data(), encQuery.length())) { setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute query"), QSqlError::StatementError, d)); return false; } d->result = mysql_store_result(d->mysql); if (!d->result && mysql_field_count(d->mysql) > 0) { setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store result"), QSqlError::StatementError, d)); return false; } int numFields = mysql_field_count(d->mysql); setSelect(numFields != 0); d->fields.resize(numFields); d->rowsAffected = mysql_affected_rows(d->mysql); if (isSelect()) { for(int i = 0; i < numFields; i++) { MYSQL_FIELD* field = mysql_fetch_field_direct(d->result, i); d->fields[i].type = qDecodeMYSQLType(field->type, field->flags); } } setActive(true); return true;}int QMYSQLResult::size(){ if (isSelect()) if (d->preparedQuerys)#if MYSQL_VERSION_ID >= 40108 return int(mysql_stmt_num_rows(d->stmt));#else return -1;#endif else return int(mysql_num_rows(d->result)); else return -1;}int QMYSQLResult::numRowsAffected(){ return d->rowsAffected;}QVariant QMYSQLResult::lastInsertId() const{ if (!isActive()) return QVariant(); if (d->preparedQuerys) {#if MYSQL_VERSION_ID >= 40108 quint64 id = mysql_stmt_insert_id(d->stmt); if (id) return QVariant(id);#endif } else { quint64 id = mysql_insert_id(d->mysql); if (id) return QVariant(id); } return QVariant();}QSqlRecord QMYSQLResult::record() const{ QSqlRecord info; MYSQL_RES *res; if (!isActive() || !isSelect()) return info;#if MYSQL_VERSION_ID >= 40108 res = d->preparedQuerys ? d->meta : d->result;#else res = d->result;#endif if (!mysql_errno(d->mysql)) { mysql_field_seek(res, 0); MYSQL_FIELD* field = mysql_fetch_field(res); while(field) { info.append(qToField(field, d->tc)); field = mysql_fetch_field(res); } } mysql_field_seek(res, 0); return info;}#if MYSQL_VERSION_ID >= 40108static MYSQL_TIME *toMySqlDate(QDate date, QTime time, QVariant::Type type){ Q_ASSERT(type == QVariant::Time || type == QVariant::Date || type == QVariant::DateTime); MYSQL_TIME *myTime = new MYSQL_TIME; memset(myTime, 0, sizeof(MYSQL_TIME)); if (type == QVariant::Time || type == QVariant::DateTime) { myTime->hour = time.hour(); myTime->minute = time.minute(); myTime->second = time.second(); myTime->second_part = time.msec(); } if (type == QVariant::Date || type == QVariant::DateTime) { myTime->year = date.year(); myTime->month = date.month(); myTime->day = date.day(); } return myTime;}bool QMYSQLResult::prepare(const QString& query){ cleanup(); if (!d->preparedQuerys) return QSqlResult::prepare(query); int r; if (query.isEmpty()) return false; if (!d->stmt) d->stmt = mysql_stmt_init(d->mysql); if (!d->stmt) { setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"), QSqlError::StatementError, d)); return false; } const QByteArray encQuery(fromUnicode(d->tc, query)); r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length()); if (r != 0) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"), QSqlError::StatementError, d->stmt)); cleanup(); return false; } if (mysql_stmt_param_count(d->stmt) > 0) {// allocate memory for outvalues d->outBinds = new MYSQL_BIND[mysql_stmt_param_count(d->stmt)]; } setSelect(d->bindInValues()); return true;}bool QMYSQLResult::exec(){ if (!d->preparedQuerys) return QSqlResult::exec(); if (!d->stmt) return false; int r = 0; MYSQL_BIND* currBind; QVector<MYSQL_TIME *> timeVector; QVector<QByteArray> stringVector; QVector<my_bool> nullVector; const QVector<QVariant> values = boundValues(); r = mysql_stmt_reset(d->stmt); if (r != 0) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to reset statement"), QSqlError::StatementError, d->stmt)); return false; } if (mysql_stmt_param_count(d->stmt) > 0 && mysql_stmt_param_count(d->stmt) == (uint)values.count()) { nullVector.resize(values.count()); for (int i = 0; i < values.count(); ++i) { const QVariant &val = boundValues().at(i); void *data = const_cast<void *>(val.constData()); currBind = &d->outBinds[i]; nullVector[i] = static_cast<my_bool>(val.isNull()); currBind->is_null = &nullVector[i]; currBind->length = 0; switch (val.type()) { case QVariant::ByteArray: currBind->buffer_type = MYSQL_TYPE_BLOB; currBind->buffer = const_cast<char *>(val.toByteArray().constData()); currBind->buffer_length = val.toByteArray().size(); break; case QVariant::Time: case QVariant::Date: case QVariant::DateTime: { MYSQL_TIME *myTime = toMySqlDate(val.toDate(), val.toTime(), val.type()); timeVector.append(myTime); currBind->buffer = myTime; switch(val.type()) { case QVariant::Time: currBind->buffer_type = MYSQL_TYPE_TIME; myTime->time_type = MYSQL_TIMESTAMP_TIME; break; case QVariant::Date: currBind->buffer_type = MYSQL_TYPE_DATE; myTime->time_type = MYSQL_TIMESTAMP_DATE; break; case QVariant::DateTime: currBind->buffer_type = MYSQL_TYPE_DATETIME; myTime->time_type = MYSQL_TIMESTAMP_DATETIME; break; default: break; } currBind->buffer_length = sizeof(MYSQL_TIME); currBind->length = 0; break; } case QVariant::UInt: case QVariant::Int: case QVariant::Bool: currBind->buffer_type = MYSQL_TYPE_LONG; currBind->buffer = data; currBind->buffer_length = sizeof(int); currBind->is_unsigned = (val.type() != QVariant::Int); break; case QVariant::Double: currBind->buffer_type = MYSQL_TYPE_DOUBLE; currBind->buffer = data; currBind->buffer_length = sizeof(double); currBind->is_unsigned = 0; break; case QVariant::LongLong: case QVariant::ULongLong: currBind->buffer_type = MYSQL_TYPE_LONGLONG; currBind->buffer = data; currBind->buffer_length = sizeof(qint64); currBind->is_unsigned = (val.type() == QVariant::ULongLong); break; case QVariant::String: default: { QByteArray ba = fromUnicode(d->tc, val.toString()); stringVector.append(ba); currBind->buffer_type = MYSQL_TYPE_STRING; currBind->buffer = const_cast<char *>(ba.constData()); currBind->buffer_length = ba.length(); currBind->is_unsigned = 0; break; } } } r = mysql_stmt_bind_param(d->stmt, d->outBinds); if (r != 0) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to bind value"), QSqlError::StatementError, d->stmt)); qDeleteAll(timeVector); return false; } } r = mysql_stmt_execute(d->stmt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -