Different versions of Qt with different versions of MySQL
-
I have been a long time user of Qt. I primarily code on Ubuntu, so my query here relates only to Ubuntu distributions.
Now as of yesterday, Ubuntu 20.04 LTS has been released. I was using Ubuntu 18.04 before this. Now Ubuntu 18.04 use to ship with both MySQL 5.x and MySQL 8.x and it was upto the user which version to install.
With 20.04, the default package is MySQL 8.x only. I do not have any issues with using version 8, its just that version 8 does not seem to have compatibility with Qt 5.9.9.
I have recently developed apps based on Qt 5.9.9 that utilize MySQL 5.I always download the Qt installers from the Qt website, and build my own MySQL plugins. So when I was trying to set up Qt 5.9.9 in Ubuntu 20.04, I realized that the plugin simply would not compile. I then went ahead and downloaded Qt 5.14.2 (latest as of posting this), followed the same steps for building MySQL plugin, and it went ahead without any problems.
So my question is, is there a way to use MySQL 8 in Qt 5.9.9? Or can I run separate versions of Qt with separate versions of MySQL (PREFERABLY DONT WANT THIS).
Other option is to use MariaDB, but I do not seem to find any guide to install it. Also MariaDB 10.4 seems to be based on a fork of MySQL 8.Any ideas or suggestions?
-
@vinit320 said in Different versions of Qt with different versions of MySQL:
Have you tried building plugin for MySQL 8 using Qt 5.9.9?
No. If you share what you did and what problems/errors you got maybe somebody can help
-
OK.
To summarize, I have the following installed on Ubuntu 20.04:
- mysql-server (version 8)
- mysql-client
- libmysqlclient-dev
- Qt 5.9.9 with source (downloaded from qt website)
- libssl-dev
Since this has been installed via apt, I do not need to explicitly give paths while building the plugin. So now I go into the Qt 5.9.9 directory as follows:
cd /opt/Qt5.9.9/5.9.9/Src/qtbase/src/plugins/sqldrivers
There, I execute command:
sudo /opt/Qt5.9.9/5.9.9/gcc_64/bin/qmake
On this, I get the following output:
Running configuration tests... Checking for DB2 (IBM)... no Checking for InterBase... no Checking for MySQL... yes Checking for OCI (Oracle)... no Checking for ODBC... no Checking for PostgreSQL... no Checking for SQLite (version 2)... no Checking for TDS (Sybase)... no Done running configuration tests. Configure summary: Qt Sql: DB2 (IBM) .............................. no InterBase .............................. no MySql .................................. yes OCI (Oracle) ........................... no ODBC ................................... no PostgreSQL ............................. no SQLite2 ................................ no SQLite ................................. yes Using system provided SQLite ......... no TDS (Sybase) ........................... no Qt is now configured for building. Just run 'make'. Once everything is built, Qt is installed. You should NOT run 'make install'. Note that this build cannot be deployed to other machines or devices. Prior to reconfiguration, make sure you remove any leftovers from the previous build.
This shows that MySQL has been detected correctly. All is well and good.
Now, I go ahead and run make as follows (still in the same directory):
sudo make
And here's where the trouble begins. I get the following output:
vinit320@vinit-desktop:/opt/Qt5.9.9/5.9.9/Src/qtbase/src/plugins/sqldrivers$ sudo make cd mysql/ && ( test -e Makefile || /opt/Qt5.9.9/5.9.9/gcc_64/bin/qmake -o Makefile /opt/Qt5.9.9/5.9.9/Src/qtbase/src/plugins/sqldrivers/mysql/mysql.pro ) && make -f Makefile make[1]: Entering directory '/opt/Qt5.9.9/5.9.9/Src/qtbase/src/plugins/sqldrivers/mysql' g++ -c -pipe -O2 -std=c++1z -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions -Wall -W -Wvla -Wdate-time -D_REENTRANT -fPIC -DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT -DQT_NO_CAST_TO_ASCII -DQT_NO_CAST_FROM_ASCII -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_PLUGIN -DQT_SQL_LIB -DQT_CORE_LIB -I. -I/opt/Qt5.9.9/5.9.9/gcc_64/include/QtSql/5.9.9 -I/opt/Qt5.9.9/5.9.9/gcc_64/include/QtSql/5.9.9/QtSql -I/opt/Qt5.9.9/5.9.9/gcc_64/include/QtCore/5.9.9 -I/opt/Qt5.9.9/5.9.9/gcc_64/include/QtCore/5.9.9/QtCore -I/opt/Qt5.9.9/5.9.9/gcc_64/include -I/opt/Qt5.9.9/5.9.9/gcc_64/include/QtSql -I/opt/Qt5.9.9/5.9.9/gcc_64/include/QtCore -I.moc -isystem /usr/include/mysql -I/opt/Qt5.9.9/5.9.9/gcc_64/mkspecs/linux-g++ -o .obj/qsql_mysql.o qsql_mysql.cpp In file included from qsql_mysql.cpp:43: /opt/Qt5.9.9/5.9.9/gcc_64/include/QtCore/qvariant.h: In constructor ‘QVariant::QVariant(QVariant&&)’: /opt/Qt5.9.9/5.9.9/gcc_64/include/QtCore/qvariant.h:265:25: warning: implicitly-declared ‘constexpr QVariant::Private& QVariant::Private::operator=(const QVariant::Private&)’ is deprecated [-Wdeprecated-copy] 265 | { other.d = Private(); } | ^ /opt/Qt5.9.9/5.9.9/gcc_64/include/QtCore/qvariant.h:380:16: note: because ‘QVariant::Private’ has user-provided ‘QVariant::Private::Private(const QVariant::Private&)’ 380 | inline Private(const Private &other) Q_DECL_NOTHROW | ^~~~~~~ qsql_mysql.cpp: At global scope: qsql_mysql.cpp:235:9: error: ‘my_bool’ does not name a type; did you mean ‘bool’? 235 | my_bool nullIndicator; | ^~~~~~~ | bool qsql_mysql.cpp: In constructor ‘QMYSQLResultPrivate::QMyField::QMyField()’: qsql_mysql.cpp:231:28: error: class ‘QMYSQLResultPrivate::QMyField’ does not have any field named ‘nullIndicator’ 231 | : outField(0), nullIndicator(false), bufLength(0ul), | ^~~~~~~~~~~~~ qsql_mysql.cpp: In member function ‘bool QMYSQLResultPrivate::bindInValues()’: qsql_mysql.cpp:429:28: error: ‘struct QMYSQLResultPrivate::QMyField’ has no member named ‘nullIndicator’ 429 | bind->is_null = &f.nullIndicator; | ^~~~~~~~~~~~~ qsql_mysql.cpp: In member function ‘virtual QVariant QMYSQLResult::data(int)’: qsql_mysql.cpp:640:15: error: ‘const struct QMYSQLResultPrivate::QMyField’ has no member named ‘nullIndicator’ 640 | if (f.nullIndicator) | ^~~~~~~~~~~~~ qsql_mysql.cpp: In member function ‘virtual bool QMYSQLResult::isNull(int)’: qsql_mysql.cpp:733:35: error: ‘const struct QMYSQLResultPrivate::QMyField’ has no member named ‘nullIndicator’ 733 | return d->fields.at(field).nullIndicator; | ^~~~~~~~~~~~~ qsql_mysql.cpp: In member function ‘virtual bool QMYSQLResult::exec()’: qsql_mysql.cpp:986:13: error: ‘my_bool’ was not declared in this scope; did you mean ‘bool’? 986 | QVector<my_bool> nullVector; | ^~~~~~~ | bool qsql_mysql.cpp:986:20: error: template argument 1 is invalid 986 | QVector<my_bool> nullVector; | ^ qsql_mysql.cpp:1000:20: error: request for member ‘resize’ in ‘nullVector’, which is of non-class type ‘int’ 1000 | nullVector.resize(values.count()); | ^~~~~~ qsql_mysql.cpp:1007:25: error: invalid types ‘int[int]’ for array subscript 1007 | nullVector[i] = static_cast<my_bool>(val.isNull()); | ^ qsql_mysql.cpp:1007:41: error: ‘my_bool’ does not name a type; did you mean ‘bool’? 1007 | nullVector[i] = static_cast<my_bool>(val.isNull()); | ^~~~~~~ | bool qsql_mysql.cpp:1008:46: error: invalid types ‘int[int]’ for array subscript 1008 | currBind->is_null = &nullVector[i]; | ^ qsql_mysql.cpp:1104:16: error: expected ‘;’ before ‘update_max_length’ 1104 | my_bool update_max_length = true; | ^~~~~~~~~~~~~~~~~~ | ; qsql_mysql.cpp:1113:72: error: ‘update_max_length’ was not declared in this scope 1113 | mysql_stmt_attr_set(d->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &update_max_length); | ^~~~~~~~~~~~~~~~~ qsql_mysql.cpp: In member function ‘virtual bool QMYSQLDriver::open(const QString&, const QString&, const QString&, const QString&, int, const QString&)’: qsql_mysql.cpp:1315:5: error: ‘my_bool’ was not declared in this scope; did you mean ‘bool’? 1315 | my_bool reconnect=false; | ^~~~~~~ | bool qsql_mysql.cpp:1333:21: error: ‘reconnect’ was not declared in this scope; did you mean ‘connect’? 1333 | reconnect = true; | ^~~~~~~~~ | connect qsql_mysql.cpp:1414:13: error: ‘reconnect’ was not declared in this scope; did you mean ‘connect’? 1414 | if (reconnect) | ^~~~~~~~~ | connect make[1]: *** [Makefile:738: .obj/qsql_mysql.o] Error 1 make[1]: Leaving directory '/opt/Qt5.9.9/5.9.9/Src/qtbase/src/plugins/sqldrivers/mysql' make: *** [Makefile:46: sub-mysql-make_first] Error 2
If the same steps are followed for Qt 5.14.2, it works and I am able to run sudo make install. This leads me to believe that Qt 5.9.9 is simply not compatible with MySQL 8.
So, any ideas what can be done?
-
Ok. So I have found the solution.
MySQL 8 replaces my_bool with bool. So if using a previous Qt version (before Qt 12 mostly), simply edit the qsql_mysql.cpp file in the src/plugins/sqldrivers/mysql directory and the following line after the #include statements.
typedef bool my_bool
Hopefully this helps someone out. Please note this is only required if using MySQL 8 on versions of QT before QT 12. QT 12+ supports native building of plugins for MySQL 8.