QtSql connection - c++

I am trying to create a connection to a database and insert/delete/make queries to the database. I know SQL relatively well but I cannot seem to wrap my head around it in Qt. I used to program in Delphi.
This is my code so far:
QSqlDatabase db;
db.addDatabase("QSQLITE");
db.setHostName( "localhost" ); //I don't know if i should include this the database is in the same directory as my program
db.setDatabaseName( "Xmato.odb" );
db.setUserName( "" ); //There is no username
db.setPassword( "" ); //There is no password
db.open();
db.prepare("SELECT * FROM Members");
db.exec();
I have added this to my .pro file:
QT += sql;
An included QtSql to my main file.
When I run this code I get the error:
QSqlQuery::prepare: database not open
Any ideas will me much appreciated.
P.S.: I use c++ on Linux Ubuntu 12.04 and used LibreOffice Base to create my database.

After a bit of google-ing - openoffice libre's internal database is using HSQLDB (natural choice for Java). Here's a small discussion about HSQLDB.
It appears that some versions of openlibre base is also able to connect to external databases. I would recommend setting up something that is more accessible to C++, specifically Qt.
Only a few drivers like ODBC & SQLite is included by default.
Which means that depending on the database being used, one may need to get additional source code (or packages) and compile a plugin/dll/so. The library is loaded dynamically (i.e. run-time) by the QtSql module. I've run into this for mysql drivers.
When you get all of that setup, your call to addDatabase should match the kind of database you're using.
QSqlDatabase::addDatabase( "QODBC" ); // For something like MSSQL
QSqlDatabase::addDatabase( "QSQLITE" ); // For SQLite
QSqlDatabase::addDatabase( "QMYSQL" ); // For MySQL
Personally, if you're just doing this for kicks, a quick and easy database is SQLITE. You can even download plugins/extensions for Mozilla Firefox that will offer you a GUI to the database.

Driver not loaded
you need the QSQLITE driver.
db.drivers() returns a list of all the available database drivers.
In Ubuntu 12.04 the driver for sqlite is in a package named libqt4-sql-sqlite.
But: is odb a sqlite database??

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName( "Xmato.odb" );
if (db.open())
{
QSqlQuery query(db); // if multiple connections used, without the `db` in constructor will cause the query to use the default database (first opened and available one)
query.exec("select * from members");
}
should do the same. username and password are not needed and since it is a file, you just have to use setDatabaseName to set what file you want to open.

Related

Why can't I connect to a database the normal way with Qt?

I'm quite new to databases and trying to connect to a MySql database from my application using Qt.
The official documentation provides this example:
// I used QODBC driver because QMYSQL isn't available
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("bigblue");
db.setDatabaseName("flightdb");
db.setUserName("acarlson");
db.setPassword("1uTbSbAs");
bool ok = db.open();
But it doesn't work for me. The only way I managed to connect to my database is this:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
QString connectString = "Driver={MySQL ODBC 8.0 Unicode Driver};";
connectString.append("Server=127.0.0.1,3306;"); // IP,Port
connectString.append("Database=schema_name;"); // Schema
connectString.append("Uid=user_name;"); // User
connectString.append("Pwd=*****;"); // Password
connectString.append("MULTI_HOST=1;");
db.setDatabaseName(connectString);
It took me several days to find this solution, but now I wonder why the first one didn't work. Do you have any idea?
Also, I used MySql to create the tables and it brought another question: it might sound a bit stupid, but is there any difference between databases initialized by different DBMS? I don't know, maybe it has something to do with the driver I choose to read it...

How to check if file is appropriated with database driver in Qt

Assuming I want to open a connection to SQLite3 database in Qt. It will be connected to an existed database dbName.
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
Now I need to set db.setDatabaseName(dbName), where dbName is received through a QFileDialog.
However, as long as dbName is a valid file name, then db.open() is always true. Is there anyway to check if the file dbName is a SQLite3 database, but not of any other type? What I can do now is to execute a query and check for error like:
db.setDatabaseName(dbName);
if (db.open()) {
QSqlQuery qr(db);
if (!qr.exec(".database;")) {
qDebug() << qr.lastError().text();
return false;
}
}
but it won't work if the file is empty.
Qt always uses the SQLITE_OPEN_CREATE flag, so nonexistent or empty files are considered valid (for a new, empty database).
If you don't want to change Qt, or write your own database driver, the only alternative is to manually check for a valid database header in the file.
I had to face the same problem.
In fact, there is two issues :
1/ As CL said, Qt always uses the SQLITE_OPEN_CREATE flag, so if you try to open a database that point to a non-existent file, the database will be created and you get a success.
You can adress this issue by checking if the file exists before open (see QFile::Exists static method)
2/ SQLite use "lazy initialization", so until you make a request on the database, the file is not really opened.
You can adress this issue by executing a simple request right after the database open, and check the result.
If you don't know anything in advance about the database schema, you can try to read one of the "PRAGMA" values : http://www.sqlite.org/pragma.html#pragma_table_info

Connecting to ACCDB using QT5

What I'm trying to do is find all .db (Paradox) files from a directory and save them to .mdb. The thing is, to try if this works properly I've tried first opening an ACCDB (.db and .mdb I'll be using are resources only available in my school's internal network).
I've already checked, and I've found the sql drivers in the Qt directory, I've also added QT +=sql in my pro file, I've installed the access database engine, VBA is also installed, but I can't manage to open the connection. I'm yet to try connecting to a SQLITE database to try if it works, but I'm guessing it will. Here is the code, triggered from a button:
db.addDatabase("QODBC");
explorador.setFileMode(QFileDialog::Directory);
ruta=explorador.getExistingDirectory(this,"Seleccionar directorio");
directorio.setPath(ruta);
subdir=directorio.entryList(QDir::AllDirs);
//La lista comienza en el 2ยบ elemento
for(int i=2;i<subdir.size();i++)
{
subruta=ruta+"/"+subdir.at(i);
directorio.setPath(subruta);
db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ="+subruta+"/Base de datos11.accdb");
bool check=db.open();
if(check)
{
dbg.setText("Prueba");
dbg.show();
}
else
{
dbg.setText("Pruebaaa");
dbg.show();
}
}
Have any ideas?? Thank you!
I eventually solved it kind of bypassing through access. If someone else is struggling with this you need:
-Paradox DB engine (Be sure the version you download matches your .db file)
-Jet engine 4.0 or later
-access 2007 (Following version have removed Paradox DB connection)
-Administrator privileges to access the database engine folders(both jet and paradox)
Simply open the database through a connection or database object. Sintax should be something like this (Via a VBA module in access):
database.open(path,*Dont rememer what goes in here,*here goes the read/write permits,"Paradox 5.x")
Path should be pointing to a folder containing one or more .db files, which will be opened as a a single database with the files being tables. It actually genereates a new database (Either .accdb or .mdb, depending how you save it)
It is not exactly like this, but I'm on my laptop. I'll edit the answer once I'm in front of my code
Sorry it is not a c++ answer, but from what I've found it is kind of a pain in the a** to work with paradox databases. Hope this helps others with the struggle.
Ricardo

Qt SQL - Configuring Connection to Database

I have given up on trying to configure the MYSQL driver for the Qt 5.0 library, I am going to use the only driver currently available to me - "QSQLITE".
I have been trying to get this working for quite some time and have tried everything mentioned in similar posts:
Select from SQLite with Qt
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setHostName(SQL_SERVER);
db.setPort(SQL_PORT);
db.setDatabaseName(SQL_DATABASE);
db.setUserName(SQL_USER);
db.setPassword(SQL_PASS);
bool dbSuccess = db.open();
QList<QString> deviceNames;
QString deviceName;
qDebug() << db;
if(dbSuccess){
QSqlQuery query;
qWarning("We made it into the DB");
query.exec("SELECT device_name FROM tbl_device");
while (query.next() ){
qDebug() << query.value(1).toString();
// deviceNames.append(deviceName);
//qDebug() << "Test: "<< deviceName;
}
}
else if(!db.open()){
qWarning("Database failed to load!");
}
Where SQL_Server = 192.168.1.100
I get the following qDebug output from the application:
QSqlDatabase(driver=""QSQLITE"", database=""homelogic"", host=""hendrenserver"", port=3306, user=""homelogic"", open=true)
We made it into the DB
The output suggests that the database connection is valid, however if I change the servername to something completely false such as "xlkcjox" or other random keys - I get the same output. What am I missing here? I feel like this should be relatively easy.
Please advise!
When using the sqlite driver for qt, the database name is a file on your disc, regardless of the host name. This is how sqlite works. It needs no host just a filename.
I am revisiting this question to share a very helpful link that I came across today. I reached a solution using Qt 4.8.4 and QODBC driver. Due to a need to use QSerialPort and project bugs, I updated to 5.0.1 today. When working on rebuilding my ODBC plugin, I found this link: http://seppemagiels.com/blog/create-mysql-driver-qt5-windows.
Within 20 minutes I had what I originally wanted, the QMYSQL driver, working. I hope this helps others!

Do I need an SQL server to work with Qt's QtSql library?

I am a beginner with Qt, so my question might be a bit basic.
My intention is to work with an ODBC database located in my hard drive. I have tried to open it with this code:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setHostName("");
db.setDatabaseName("c:\\database.mdb");
bool ok = db.open();
QSqlQuery query;
query.exec("SELECT name FROM results WHERE tag>10");
while (query.next()) {
QString name1 = query.value(0).toString();
qDebug() << name1;
}
Now, the problem is that the program can't find the database, failing at the db.open() line. I suspect that Qt can't open a database directly, but instead has to deal with an SQL server. Is this so? If that's the case, I'd be grateful if you could give me some clues on how to go ahead, particularly regarding host name (is it localhost?).
Also, I am not sure of whether the path to the file must be included in DatabaseName.
PS: I have no problem shifting to a different kind of database/server, e.g. MySQL. So if your solution requires this, I'd be happy with it!
Thanks in advance
D
Unless you specifically need a Jet/MS Access format database for something else you'd be better off going with SQLite. Qt has SQLite support built-in (QSQLITE driver) - you just point it at the database file and go. No need to setup ODBC data sources or anything.
According to the documentation, you should set the setDatabaseName to the ODBC datasource. You then configure the ODBC datasource to point to the appropriate file.
For future reference:
Just as Werne Strydom said, the argument of setDatabaseName is not the database file name, but the name of the ODBC datasource that points to your database. Therefore, you need to create an ODBC that points to your database.
The usual way to do this (in Windows) would be to go to Control Panel\System & security\Administrative tools\Data Sources (ODBC). But if you're in a 64-bit machine and want to work with a 32-bit driver, go instead to C:\windows\SysWOW64 and run odbcad32.exe
When you do this, a dialog opens (same dialog regardless of 64/32-bits). Here you create your ODBC, give it a name and link it to your actual database. In my case, as I am working with a local database, I used the "User DNS" tab.
Then, back in Qt, you put that ODBC name as argument for setDatabaseName. And it works! (Or it did for me...)
The new bit of code looks like:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setHostName("localhost");
db.setDatabaseName("MyDataSource");
bool ok = db.open();
QSqlQuery query;
query.exec("SELECT name FROM results WHERE tag>10");
while (query.next()) {
QString name1 = query.value(0).toString();
qDebug() << name1;
}
where "MyDataSource" is the name I gave to the ODCB.