Details
-
Bug
-
Resolution: Invalid
-
Not Evaluated
-
None
-
6.4.0
-
None
Description
(Added compilable example at the bottom)
I'm connecting to a remote Azure Database, which is successful.
Then loading a plugin/driver, which also goes successfully.
The code that does it, works, here it is (i removed the credentials to database):
void ManagerDB::connectToDB(){
qInfo() << "Establishing default connection";
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("");
db.setDatabaseName("");
db.setUserName("");
db.setPassword("");
if(!db.open())
{ qCritical() << "Failed to establish default connection!"; qCritical() << db.lastError().text(); return; } qInfo() << "Established default connection successfully";
}
//function that loads the driver:
bool ManagerDB::loadDriver(){
qInfo() << "Loading driver/plugin";
QPluginLoader loader("/home/roditu/Qt/6.5.1/gcc_64/plugins/sqldrivers/libqsqlmysql.so");
qInfo() << loader.metaData();
if(loader.load())
{ qInfo() << "Loaded the plugin"; return true; } qCritical() << loader.errorString();
return false;
}
I'm using libqsqlmysql.so driver, maybe that matters.
In the database I'm creating a simple procedure with the following MySQL code:
CREATE PROCEDURE validate_credentials(IN in_login VARCHAR(20), IN in_password VARCHAR(20), INOUT out_is_valid BOOLEAN)
BEGIN
SET out_is_valid = TRUE;
SELECT TRUE INTO out_is_valid; --without this line won't work anyway
END;
This procedure is meant to be Called in QT with QSqlQuery and return a TRUE boolean value. It's purpose in project it's different, but i simplified it to this state and it still doesn't work. You see even though I set "out_is_valid" to true always, as simple as it is in MySQL here, it always returns false in QT c++ code, or at least the QT code always reads the same value that was sent to the procedure in the first place (it doesn't change).
The query itself doesn't throw any error (the "query.exec()" returns true).
So after establishing connection with the database and loading a plugin, this code is simply executed:
QSqlQuery query{};
bool isValid{false};
//validate_credentials(IN in_login VARCHAR(20), IN in_password VARCHAR(20), OUT out_is_valid BOOLEAN)
query.prepare("CALL validate_credentials(?, ?, ?)");
query.bindValue(0, login);
query.bindValue(1, password);
query.bindValue(2, QVariant(false), QSql::InOut);
if(query.exec())
{ isValid = query.boundValue(2).toBool(); qInfo() << isValid; }else
{ qWarning() << "Failed to execute validate_credentials: " << query.lastError().text(); }In the line "qInfo() << isValid" I want to display a true boolean value, i'm sending false to the query and i change it to true and return it and print it out, but the value simply doesn't change, if it's QVariant(false) it will be still false after the query and it will print false.
This query code is as from this documentation: https://doc.qt.io/qt-5/qsqlquery.html#approaches-to-binding-values
Compilable example:
Main.cpp:
#include <QCoreApplication>
#include <QtSql/qsqldatabase.h>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlDriver>
#include <QPluginLoader>
#include <QSqlError>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qInfo() << "Establishing default connection";
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName(""); //Your remote database credentials
db.setDatabaseName("");
db.setUserName("");
db.setPassword("");
if(!db.open())
{ qCritical() << "Failed to establish default connection!"; qCritical() << db.lastError().text(); }qInfo() << "Established default connection successfully";
qInfo() << "Loading driver/plugin";
QPluginLoader loader(""); //Your path to libqsqlmysql.so driver
qInfo() << loader.metaData();
if(loader.load())
{ qInfo() << "Loaded the plugin"; }qCritical() << loader.errorString();
QSqlQuery query{};
bool isValid{false};
//Remote database needs to have defined this procedure, and the User needs
//permission to it.
//validate_credentials(IN in_login VARCHAR(20), IN in_password VARCHAR(20), OUT out_is_valid BOOLEAN)
query.prepare("CALL validate_credentials(?, ?, ?)");
//this procedure should set the OUT parameter to true and return it
/*
CREATE PROCEDURE validate_credentials(IN in_login VARCHAR(20), IN in_password VARCHAR(20), INOUT out_is_valid BOOLEAN)
BEGIN
SET out_is_valid = TRUE;
SELECT TRUE INTO out_is_valid;
END;
*/
query.bindValue(0, "example");
query.bindValue(1, "example");
query.bindValue(2, QVariant(false), QSql::InOut);
if(query.exec())
{ isValid = query.boundValue(2).toBool(); //bug: it will display false and not true qInfo() << isValid; }else
{ qWarning() << "Failed to execute validate_credentials: " << query.lastError().text(); } return a.exec();
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project(compilableExample LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Sql)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Sql)
add_executable(compilableExample
main.cpp
)
target_link_libraries(compilableExample
PRIVATE Qt${QT_VERSION_MAJOR}::Sql
Qt${QT_VERSION_MAJOR}::Core)
install(TARGETS compilableExample
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)