?? qsql_mysql.cpp
字號:
} r = mysql_stmt_execute(d->stmt); qDeleteAll(timeVector); if (r != 0) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to execute statement"), QSqlError::StatementError, d->stmt)); return false; } //if there is meta-data there is also data setSelect(d->meta); d->rowsAffected = mysql_stmt_affected_rows(d->stmt); if (isSelect()) { my_bool update_max_length = true; r = mysql_stmt_bind_result(d->stmt, d->inBinds); if (r != 0) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to bind outvalues"), QSqlError::StatementError, d->stmt)); return false; } if (d->hasBlobs) mysql_stmt_attr_set(d->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &update_max_length); r = mysql_stmt_store_result(d->stmt); if (r != 0) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to store statement results"), QSqlError::StatementError, d->stmt)); return false; } if (d->hasBlobs) { // mysql_stmt_store_result() with STMT_ATTR_UPDATE_MAX_LENGTH set to true crashes // when called without a preceding call to mysql_stmt_bind_result() // in versions < 4.1.8 d->bindBlobs(); r = mysql_stmt_bind_result(d->stmt, d->inBinds); if (r != 0) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", "Unable to bind outvalues"), QSqlError::StatementError, d->stmt)); return false; } } setAt(QSql::BeforeFirstRow); } setActive(true); return true;}#endif/////////////////////////////////////////////////////////static void qServerInit(){#ifndef Q_NO_MYSQL_EMBEDDED# if MYSQL_VERSION_ID >= 40000 static bool init = false; if (init) return; // this should only be called once // has no effect on client/server library // but is vital for the embedded lib if (mysql_server_init(0, 0, 0)) { qWarning("QMYSQLDriver::qServerInit: unable to start server."); } init = true;# endif // MYSQL_VERSION_ID#endif // Q_NO_MYSQL_EMBEDDED}QMYSQLDriver::QMYSQLDriver(QObject * parent) : QSqlDriver(parent){ init(); qServerInit();}/*! Create a driver instance with the open connection handle, \a con. The instance's parent (owner) is \a parent.*/QMYSQLDriver::QMYSQLDriver(MYSQL * con, QObject * parent) : QSqlDriver(parent){ init(); if (con) { d->mysql = (MYSQL *) con;#ifndef QT_NO_TEXTCODEC d->tc = codec(con);#endif setOpen(true); setOpenError(false); } else { qServerInit(); }}void QMYSQLDriver::init(){ d = new QMYSQLDriverPrivate(); d->mysql = 0;}QMYSQLDriver::~QMYSQLDriver(){ delete d;#ifndef Q_NO_MYSQL_EMBEDDED# if MYSQL_VERSION_ID > 40000 mysql_server_end();# endif#endif}bool QMYSQLDriver::hasFeature(DriverFeature f) const{ switch (f) { case Transactions:// CLIENT_TRANSACTION should be defined in all recent mysql client libs > 3.23.34#ifdef CLIENT_TRANSACTIONS if (d->mysql) { if ((d->mysql->server_capabilities & CLIENT_TRANSACTIONS) == CLIENT_TRANSACTIONS) return true; }#endif return false; case NamedPlaceholders: case BatchOperations: return false; case QuerySize: case BLOB: case LastInsertId: return true; case Unicode: return true; case PreparedQueries: case PositionalPlaceholders:#if MYSQL_VERSION_ID >= 40108 return d->preparedQuerysEnabled;#else return false;#endif } return false;}static void setOptionFlag(uint &optionFlags, const QString &opt){ if (opt == QLatin1String("CLIENT_COMPRESS")) optionFlags |= CLIENT_COMPRESS; else if (opt == QLatin1String("CLIENT_FOUND_ROWS")) optionFlags |= CLIENT_FOUND_ROWS; else if (opt == QLatin1String("CLIENT_IGNORE_SPACE")) optionFlags |= CLIENT_IGNORE_SPACE; else if (opt == QLatin1String("CLIENT_INTERACTIVE")) optionFlags |= CLIENT_INTERACTIVE; else if (opt == QLatin1String("CLIENT_NO_SCHEMA")) optionFlags |= CLIENT_NO_SCHEMA; else if (opt == QLatin1String("CLIENT_ODBC")) optionFlags |= CLIENT_ODBC; else if (opt == QLatin1String("CLIENT_SSL")) optionFlags |= CLIENT_SSL; else qWarning("QMYSQLDriver::open: Unknown connect option '%s'", opt.toLocal8Bit().constData());}bool QMYSQLDriver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port, const QString& connOpts){ if (isOpen()) close(); /* This is a hack to get MySQL's stored procedure support working. Since a stored procedure _may_ return multiple result sets, we have to enable CLIEN_MULTI_STATEMENTS here, otherwise _any_ stored procedure call will fail. */ unsigned int optionFlags = Q_CLIENT_MULTI_STATEMENTS; const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); QString unixSocket; // extract the real options from the string for (int i = 0; i < opts.count(); ++i) { QString tmp(opts.at(i).simplified()); int idx; if ((idx = tmp.indexOf(QLatin1Char('='))) != -1) { QString val = tmp.mid(idx + 1).simplified(); QString opt = tmp.left(idx).simplified(); if (opt == QLatin1String("UNIX_SOCKET")) unixSocket = val; else if (val == QLatin1String("TRUE") || val == QLatin1String("1")) setOptionFlag(optionFlags, tmp.left(idx).simplified()); else qWarning("QMYSQLDriver::open: Illegal connect option value '%s'", tmp.toLocal8Bit().constData()); } else { setOptionFlag(optionFlags, tmp); } } if ((d->mysql = mysql_init((MYSQL*) 0)) && mysql_real_connect(d->mysql, host.isNull() ? static_cast<const char *>(0) : host.toLocal8Bit().constData(), user.isNull() ? static_cast<const char *>(0) : user.toLocal8Bit().constData(), password.isNull() ? static_cast<const char *>(0) : password.toLocal8Bit().constData(), db.isNull() ? static_cast<const char *>(0) : db.toLocal8Bit().constData(), (port > -1) ? port : 0, unixSocket.isNull() ? static_cast<const char *>(0) : unixSocket.toLocal8Bit().constData(), optionFlags)) { if (!db.isEmpty() && mysql_select_db(d->mysql, db.toLocal8Bit().constData())) { setLastError(qMakeError(tr("Unable to open database '") + db + QLatin1Char('\''), QSqlError::ConnectionError, d)); mysql_close(d->mysql); setOpenError(true); return false; } } else { setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d)); mysql_close(d->mysql); setOpenError(true); return false; }#if MYSQL_VERSION_ID >= 50007 // force the communication to be utf8 mysql_set_character_set(d->mysql, "utf8");#endif#ifndef QT_NO_TEXTCODEC d->tc = codec(d->mysql);#endif#if MYSQL_VERSION_ID >= 40108 d->preparedQuerysEnabled = mysql_get_client_version() >= 40108 && mysql_get_server_version(d->mysql) >= 40100;#else d->preparedQuerysEnabled = false;#endif setOpen(true); setOpenError(false); return true;}void QMYSQLDriver::close(){ if (isOpen()) { mysql_close(d->mysql); setOpen(false); setOpenError(false); }}QSqlResult *QMYSQLDriver::createResult() const{ return new QMYSQLResult(this);}QStringList QMYSQLDriver::tables(QSql::TableType type) const{ QStringList tl; if (!isOpen()) return tl; if (!(type & QSql::Tables)) return tl; MYSQL_RES* tableRes = mysql_list_tables(d->mysql, NULL); MYSQL_ROW row; int i = 0; while (tableRes) { mysql_data_seek(tableRes, i); row = mysql_fetch_row(tableRes); if (!row) break; tl.append(toUnicode(d->tc, row[0])); i++; } mysql_free_result(tableRes); return tl;}QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const{ QSqlIndex idx; bool prepQ; if (!isOpen()) return idx; prepQ = d->preparedQuerys; d->preparedQuerys = false; QSqlQuery i(createResult()); QString stmt(QLatin1String("show index from %1;")); QSqlRecord fil = record(tablename); i.exec(stmt.arg(tablename)); while (i.isActive() && i.next()) { if (i.value(2).toString() == QLatin1String("PRIMARY")) { idx.append(fil.field(i.value(4).toString())); idx.setCursorName(i.value(0).toString()); idx.setName(i.value(2).toString()); } } d->preparedQuerys = prepQ; return idx;}QSqlRecord QMYSQLDriver::record(const QString& tablename) const{ QSqlRecord info; if (!isOpen()) return info; MYSQL_RES* r = mysql_list_fields(d->mysql, tablename.toLocal8Bit().constData(), 0); if (!r) { return info; } MYSQL_FIELD* field; while ((field = mysql_fetch_field(r))) info.append(qToField(field, d->tc)); mysql_free_result(r); return info;}QVariant QMYSQLDriver::handle() const{ return qVariantFromValue(d->mysql);}bool QMYSQLDriver::beginTransaction(){#ifndef CLIENT_TRANSACTIONS return false;#endif if (!isOpen()) { qWarning("QMYSQLDriver::beginTransaction: Database not open"); return false; } if (mysql_query(d->mysql, "BEGIN WORK")) { setLastError(qMakeError(tr("Unable to begin transaction"), QSqlError::StatementError, d)); return false; } return true;}bool QMYSQLDriver::commitTransaction(){#ifndef CLIENT_TRANSACTIONS return false;#endif if (!isOpen()) { qWarning("QMYSQLDriver::commitTransaction: Database not open"); return false; } if (mysql_query(d->mysql, "COMMIT")) { setLastError(qMakeError(tr("Unable to commit transaction"), QSqlError::StatementError, d)); return false; } return true;}bool QMYSQLDriver::rollbackTransaction(){#ifndef CLIENT_TRANSACTIONS return false;#endif if (!isOpen()) { qWarning("QMYSQLDriver::rollbackTransaction: Database not open"); return false; } if (mysql_query(d->mysql, "ROLLBACK")) { setLastError(qMakeError(tr("Unable to rollback transaction"), QSqlError::StatementError, d)); return false; } return true;}QString QMYSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const{ QString r; if (field.isNull()) { r = QLatin1String("NULL"); } else { switch(field.type()) { case QVariant::String: // Escape '\' characters r = QSqlDriver::formatValue(field, trimStrings); r.replace(QLatin1String("\\"), QLatin1String("\\\\")); break; case QVariant::ByteArray: if (isOpen()) { const QByteArray ba = field.value().toByteArray(); // buffer has to be at least length*2+1 bytes char* buffer = new char[ba.size() * 2 + 1]; int escapedSize = int(mysql_real_escape_string(d->mysql, buffer, ba.data(), ba.size())); r.reserve(escapedSize + 3); r.append(QLatin1Char('\'')).append(toUnicode(d->tc, buffer)).append(QLatin1Char('\'')); delete[] buffer; break; } else { qWarning("QMYSQLDriver::formatValue: Database not open"); } // fall through default: r = QSqlDriver::formatValue(field, trimStrings); } } return r;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -