Unable to connect to remote database
-
Hello fellow Qt'ers
I'm in dire need of some help, i apologize beforehand for the wall of text, just trying to explain everything as best as i can.
I have some issues connecting my application to a MySQL database running at a remote Linux virtual machine.
All required drivers load accordingly but the application refrains to connect.
The server runs, as mentioned, on a virtual machine, with the appropriate virtual network adapter that allows internal connections inside my computer to it.
I'm capable of pinging the server, checking that the MySQL daemon is running properly and has port no. 3306 open on it with an nmap scan, with the shell commands netstat -a | grep mysql and #service mysql status on the server. Also i'm capable of mundanely connecting to it with the MySQL Workbench developer IDE from the host machine with the same configurations i've set for the Qt application i'm developing.Host system where app is being developed is Windows, MySQL server runs Linux.
I've already uninstalled my third-party firewall just to be sure it wasn't that, which... Wasn't indeed.
Also, i've compiled the qmysql driver from source with the mscv2015 compiler that i also use to compile my Qt project,, and properly installed it at sqldrivers under mscv2015 at the Qt directory.
I also copied the mysql headers and library onto the qt compiler/kit include and lib directories, and properly set up the INCLUDEPATH and LIB environment variables.
INCLUDEPATH -> C:\Program Files\MySQL\MySQL Server 5.5\include
LIB -> C:\Program Files\MySQL\MySQL Server 5.5\libAs anyone else come across such issues?
Thanks in advance. Here's my code just in case:
main.cpp
#include <QCoreApplication>
#include <QApplication>
#include <QtSql>
#include <QDebug>
#include <QDialog>
#include <QtGui>
#include <QWidget>
#include <QTabWidget>
#include "MySQL.h"
#include "mainwindow.h"int main(int argc, char argv[])
{
QSqlDatabase pdatabase;if ((pdatabase = createConnection()) == NULL) {
qDebug() << "Not connected!" << endl;
closeConnection(pdatabase);
return 0;
} else {
qDebug() << "Connected!" << endl;QApplication app(argc, argv); QSqlQuery query; MainWindow window; query.exec("SELECT * FROM Produtos"); while (query.next()) { QString name = query.value(0).toString(); qDebug() << "name:" << name; } window.setWindowTitle(QString::fromUtf8("Loja Produtos Electronicos")); window.show(); window.~MainWindow(); closeConnection(pdatabase); query.~QSqlQuery(); app.~QApplication(); return app.exec();
}
}mysql.h
#ifndef MYSQL_H
#define MYSQL_H#include <QApplication>
#include <QtSql/QSql>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlDriver>
#include <QDebug>
#include <QWidget>#define DATABASE_TYPE "QMYSQL"
#define DATABASE_NAME "loja_tech"
#define HOST "192.168.56.101"
#define DATABASE "loja_tech"
#define USER "root"
#define PASSWORD ""
#define PORT 3306#endif
QSqlDatabase* createConnection(void);
void closeConnection(QSqlDatabase*);mysql.cpp
#include "MySQL.h"
QSqlDatabase* createConnection(void)
{
qDebug() << "Plugins loaded from: " << QCoreApplication::libraryPaths();
QSqlDatabase* db = new QSqlDatabase;
db->addDatabase(DATABASE_TYPE, DATABASE_NAME);
db->setHostName(HOST);
db->setDatabaseName(DATABASE);
db->setUserName(USER);
db->setPassword(PASSWORD);
db->setPort(PORT);if (db->open()) { qDebug() << "Successfully connected to database!" << endl; return db; } else { qDebug() << "Database error occurred" << endl; return NULL; }
}
void closeConnection(QSqlDatabase* db)
{
if(db->open()) {
db->close();
}
db->~QSqlDatabase();
delete(db);return;
}
-
Hi and welcome to devnet,
Please take a look again at QSqlDatabase's detailed documentation. You'll see how to setup the connection.
What you are actually doing is create an invalid QSqlDatabase object and call the static addDatabase function on it thus you are trying to configure an invalid object.
-
Hi and welcome to devnet,
Please take a look again at QSqlDatabase's detailed documentation. You'll see how to setup the connection.
What you are actually doing is create an invalid QSqlDatabase object and call the static addDatabase function on it thus you are trying to configure an invalid object.
Thank you so much, i've spent the last days trying to debug the problem and i never thought it could be an initialization issue. This is my first time using Qt.
It now finally connects to the remote database. Again, thanks!
Here is my modified code if someone else comes across this issue.
mysql.cpp
#include "MySQL.h"
QSqlDatabase createConnection(void)
{
qDebug() << "Plugins loaded from: " << QCoreApplication::libraryPaths();
QSqlDatabase db = QSqlDatabase::addDatabase(DATABASE_TYPE);
db.addDatabase(DATABASE_TYPE, DATABASE_NAME);
db.setHostName(HOST);
db.setDatabaseName(DATABASE);
db.setUserName(USER);
db.setPassword(PASSWORD);
db.setPort(PORT);if (db.open()) { qDebug() << "Successfully connected to database!" << endl; return db; } else { qDebug() << "Database error occurred" << endl << "Not connected!" << endl; exit(1); }
}
void closeConnection(QSqlDatabase db)
{
if(db.open()) {
db.close();
}
db.~QSqlDatabase();return;
}
mysql.h
#ifndef MYSQL_H
#define MYSQL_H#include <QApplication>
#include <QtSql/QSql>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlDriver>
#include <QDebug>
#include <QWidget>#define DATABASE_TYPE "QMYSQL"
#define DATABASE_NAME "database_name"
#define HOST "database server ip or domain"
#define DATABASE "database_name"
#define USER "root or another user"
#define PASSWORD "database user password"
#define PORT 3306 //port where mysql daemon is running#endif
QSqlDatabase createConnection(void);
void closeConnection(QSqlDatabase); -
Don't call the destructor like that. It's not a proper use case for that.
-
True indeed, since i do not use new as it's not applicable in this situation in Qt.
Therefore, this whole mysql is library is useless and should be dismantled back into main.cpp, taking care any object allocated through it without the new or malloc instructions are no more than stack allocated local variables or objects, and therefore are terminated after the createConnection function returns.
Therefore no need to call any destructors since nothing is permanently allocated in memory until it's "manually erased" by software. -
Technically, most of the times, you don't call a destructor at all yourself. It's being take care of when calling delete on your object.
-
Technically, most of the times, you don't call a destructor at all yourself. It's being take care of when calling delete on your object.
True indeed, quoted from cplusplus.com: "An expression with the delete operator, first calls the appropriate destructor (for class types), and then calls a deallocation function.".
Should use delete instead of trying to do it myself.
I'm still in the 'improving skills' stage at C++, and something tells me i'm a bit too used to the lower level C :p
-
In the case of QSqlDatabase, call removeDatabase.
QSqlDatabase handles the connection object for you so you don't need to do it yourself. What you can do in your application is when you need to e.g. run a query, you retrieve the right connection object at that time using QSqlDatabase::database
-
In the case of QSqlDatabase, call removeDatabase.
QSqlDatabase handles the connection object for you so you don't need to do it yourself. What you can do in your application is when you need to e.g. run a query, you retrieve the right connection object at that time using QSqlDatabase::database