How to access remote MySQL server using Qt5 on Linux? - c++

I need some help in updating remote MySQL database using QT5.I am working on Linux Ubuntu 12.04.I want my app to connect to remote server and write some data to it.Any help will be greatly appreciated.

Here is an example:
#include <QCoreApplication>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//use mysql driver
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
//set hostname
db.setHostName("localhost");
//set db name
db.setDatabaseName("test");
//set username and password
db.setUserName("user");
db.setPassword("pass");
//open db
bool ok = db.open();
qDebug() << "Db is open: " << ok;
//define a query
QSqlQuery query;
//set query
query.exec("SELECT * FROM `Persons`");
//get values from query
while (query.next()) {
QString LastName = query.value(1).toString();
QString FirstName = query.value(2).toString();
int age = query.value(3).toInt();
qDebug() << LastName << " " << FirstName << " " << age;
}
//close db
db.close();
return a.exec();
}

Related

Delete Key/Value Pair from configuration file qsetting

i am trying to search String in configuration file and if string match wants to delete key / value pair. i have getting qstringlist from file .
as far as my tried code is
int main(int argc, char *argv[])
{
QSettings* settings= new QSettings("/home/sidheshwar/Desktop/temp.txt", QSettings::IniFormat);
settings->beginGroup("Profiles");
const QStringList childKeys = settings->childKeys();
QStringList Keys;
QStringList values;
QString user="db-host";
QString tempUser;
foreach (const QString &childKey, childKeys)
{
Keys << childKey;
values << settings->value(childKey).toString();
}
for(int i=0;i< Keys.length();i++){
if(user == values.at(i)){
qDebug() << " keys" << Keys[i] << endl;
tempUser=Keys[i];
}
qDebug() << " tempUser" << tempUser << endl;
}
return 0;}
how can i use settings->remove(tempUser);
In the following example I show you an example of how to delete a data from the file that handles the configuration.
temp.ini before the execution.
[Profiles]
key1=db-host
key2=value2
key3=value3
main.cpp
#include <QCoreApplication>
#include <QSettings>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSettings* settings= new QSettings("temp.ini", QSettings::IniFormat);
settings->beginGroup("Profiles");
const QStringList childKeys = settings->childKeys();
QStringList Keys;
QStringList values;
QString user="db-host";
foreach (const QString &childKey, childKeys)
{
Keys << childKey;
values << settings->value(childKey).toString();
}
for(int i=0;i< Keys.length();i++){
if(user == values.at(i)){
qDebug() << " keys" << Keys[i];
settings->remove(Keys[i]);
}
qDebug() << Keys[i] << values.at(i);
}
return a.exec();
}
Output:
temp.ini after the execution
[Profiles]
key2=value2
key3=value3

Parameter count mismatch in Qtsql

I'm trying to insert data into a QtSql database, but I keep getting the error:
"Parameter count mismatch"
What could be what I'm doing wrong?
#include <QtSql>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << QSqlDatabase::drivers();
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setHostName("LOCALHOST");
db.setDatabaseName("people");
db.setUserName("root");
db.setPassword("");
if(db.open()) {
qDebug() << "Opened!";
QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (:id, :forename, :surname)");
query.bindValue(":id", 1001);
query.bindValue(":forename", "Bart");
query.bindValue(":surname", "Simpson");
query.exec();
if( !query.exec() )
qDebug() << query.lastError().text();
else
qDebug( "Inserted!" );
db.close();
} else {
qDebug() << "Not opened";
}
}
You don't have a table named person in the database. You are trying to insert values into a table that does not exist.
I think that the error message is wrong. But anyway, I added a CREATE statement to your code, so that the table is created before the INSERT statement is executed:
#include <QtSql>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
if(!db.open()){
qDebug() << "Not opened";
return 1;
}
qDebug() << "Opened!";
QSqlQuery query;
//CREATE the table before executing the INSERT statement
query.exec("CREATE TABLE person (id INTEGER, forename TEXT, surname TEXT);");
query.prepare("INSERT INTO person (id, forename, surname) "
"VALUES (:id, :forename, :surname)");
query.bindValue(":id", 1001);
query.bindValue(":forename", "Bart");
query.bindValue(":surname", "Simpson");
if( !query.exec() )
qDebug() << query.lastError().text();
else
qDebug( "Inserted!" );
return 0;
}
This prints Inserted! now. But if I comment out the CREATE statement line I get the same error in your question:
" Parameter count mismatch"

Qt Sqlite error 1 - table already exists

I have a problem with Qt and sqlite. Until recently, I didn't have any problems creating tables, but now, whenever I try to create a table (using the exact same function) I get an error message:
QSqlError("1", "Unable to fetch row", "table selections already exists")
My query strings are as follows:
CREATE TABLE external_files (path VARCHAR (255) NOT NULL, used INTEGER (12) NOT NULL);
This is the same as before too.
The strange thing is though, all the tables are created without a problem, but I still get error messages.
If you have any ideas why this happens, I would appreciate it. :)
UPDATE: Minimal, complete, verifiable example:
#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QFile>
#include <QTextStream>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "CONN");
db.setDatabaseName("test.db");
if(!db.open()){
qDebug() << "Connection failed!";
}
QFile tableListFile(":/resources/sql/tables.sql");
if(tableListFile.open(QIODevice::ReadOnly))
{
QTextStream stream(&tableListFile);
while(!stream.atEnd())
{
QString queryString = stream.readLine();
qDebug() << "Query string: " << queryString;
QSqlQuery query(queryString, db);
if(!query.exec()){
qDebug() << "Query error: " << query.lastError();
}
}
}
db.close();
return a.exec();
}
Thanks in advance.
Ok, I managed to solve the problem.
The query was executed 2 times for each query string, and that caused the error messages.
To get to the solution, i edited my code like this:
QString queryString = stream.readLine();
qDebug() << "Query string: " << queryString;
QSqlQuery query;
if(!query.exec(queryString)){
qDebug() << "Query error: " << query.lastError();
}

Why are decimals dropped in my Qt App in std::vector<double> when the data comes from MySQL?

In my Qt application I use a C++ function that fills a std::vector<double> with data from a MySQL database. The function uses MySQL Connector/C++ and does the following:
void create_price(sql::Connection *con, std::string database, std::string table, std::vector<double> &price_vec)
{
sql::Statement *stmt;
sql::ResultSet *res;
std::string use_database = "USE " + database;
stmt = con->createStatement();
stmt->execute(use_database);
use_database = "SELECT Time,LastVolume,LastPrice FROM "+ table +" WHERE LastVolume >0 OR LastPrice >0 ORDER BY Time ASC";
res = stmt->executeQuery(use_database); //will return many rows
while (res->next()) {
price_vec.push_back(res->getDouble("LastPrice"));
}
}
When I call this function with any std::vector<double> in my plain C++ application I get flawless results. However, when I call this function in my Qt application the passed vector is filled with ints. The decimal part is dropped!
It seems to be an issue with the MySQL part, since this test function returns proper doubles, even when called from within my Qt application.
void double_test(std::vector &doublevec){
//just some doubles to test.
std::vector<double> doublevec;
doublevec.push_back(1.4);
doublevec.push_back(5.324);
}
Is it possible that the double returned by the MySQL query is not actually a real double and therefore not compatible with Qt?
Any hint on what I can do to understand the problem better would also help.
EDIT: The part that establishes the connection looks like this
C++:
int main(int argc, char** argv) {
sql::Driver *driver;
sql::Connection *con;
driver = get_driver_instance();
try{
con = driver->connect("tcp://127.0.0.1:3306","root","pass");
cout << "Connection established" << endl;
}
catch(...){
cout << "Exception: Couldnt' connect to MySQL server. Check if it is running" << endl;
return 0;
}
vector<double> price;
create_price(con,"database","table",price);
driver->threadEnd();
delete con;
cout << "Job done" << endl;
return 0;
}
Qt:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// con and driver are private class members
driver = get_driver_instance();
try{
con = driver->connect("tcp://127.0.0.1:3306","root","pass");
std::cout << "Connection established" << std::endl;
}
catch(...){
std::cout << "Exception: Couldnt' connect to MySQL server. Check if it is running" << std::endl;
}
std::vector<double> price; //this vector now has doubles without decimals.
create_price(con,"database","table",price);
setupPlot();
}

QUrl parsing in QT 5

I have a QUrl as this:
https://www.example.com/index.html#token=SomeToken&user=guest
and I want to obtain the value of the token i.e. SomeToken. I know about method QUrl::queryItemValue,so this code must work:
void MainWindow::get_token(QUrl url)
{
url = url.toString().replace("?","#");
QString token = url.queryItemValue("token");
}
but in Qt5 i can't use this method,how can I parse url?
There is new QUrlQuery class in Qt5. New QUrl doesn't support this method yet, so you should use QUrlQuery for parsing (it has this and other methods). Use
QUrlQuery query(url);
qDebug() << query.queryItemValue("token");
Note: be carefull with replace because QUrlQuery gives you correct result with
?token=SomeToken not a #token=SomeToken
http://qt-project.org/doc/qt-5/qurlquery.html
QUrlQuery queryItemValue method does not work properly in Qt 5.9 So i wrote my own function to parse GET parameters
#include <QCoreApplication>
#include <QUrlQuery>
#include <QDebug>
#include <QMap>
#include <QUrl>
QMap<QString,QString> ParseUrlParameters(QString &url)
{
QMap<QString,QString> ret;
if(url.indexOf('?')==-1)
{
return ret;
}
QString tmp = url.right(url.length()-url.indexOf('?')-1);
QStringList paramlist = tmp.split('&');
for(int i=0;i<paramlist.count();i++)
{
QStringList paramarg = paramlist.at(i).split('=');
ret.insert(paramarg.at(0),paramarg.at(1));
}
return ret;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString url = "http://test1.ru/?token=test&email=test1";
QUrlQuery query(url);
qDebug() << "queryItemValue does not work in Qt 5.9.0 with dynamic QString" << query.queryItemValue("token") << "("<< endl;
qDebug() << "ParseUrlParameters(...) works fine..."<< endl;
QMapIterator<QString, QString> i(ParseUrlParameters(url));
while (i.hasNext())
{
i.next();
qDebug() << i.key() << ":" << i.value();
}
return a.exec();
}
I know this post is old but if my answer can help someone, I share :)
Tested under QT 5.15.2 and under QT 6.4.2
#include<QUrl>
#include<QUrlQuery>
#include<QDebug>
int main (int nbArg, char* listArg[])
{
// Initialization
QString myString = "https://www.factice.fr/demo.php?thing=123&subject=456&artificial=789";
QUrl myUrl(myString);
QUrlQuery myQuery(myUrl);
QMap<QString,QString> paramList; // Associative Array to Store Keys and Values
// For Each QPair
for(int i=0;i<myQuery.queryItems().size();i++)
{
// Information Display
qDebug() << myQuery.queryItems().at(i).first << " : " << myQuery.queryItems().at(i).second;
// Or Storage of Information for futur use
paramList.insert(myQuery.queryItems().at(i).first,myQuery.queryItems().at(i).second);
}
// End - For Each QPair
// Examples of Displaying Stored Information
qDebug() << paramList;
qDebug() << paramList["thing"];
}