QT sql programming - qt

include "mythread.h
mythread::mythread(int ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
db = QSqlDatabase::addDatabase("QODBC");
db.setHostName("127.0.0.1");
db.setDatabaseName("mydsn");
if (db.open())
{
qDebug() << "DB is connected!";
myquery->clear();
myquery->exec("INSERT INTO phone_table(name_) VALUES ('asdhjs')");
db.close();
}
else
{
qDebug() << "Db is not connected!" << db.lastError();
}
}
When I insert data its getting error
Myserver.exe
Myserver.exe has stopped working
Windows is checking for a solution to the problem...
Can anyone help me ?

You'll want to initialize your myquery object with your database.
Try changing your code to this.
if (db.open())
{
qDebug() << "DB is connected!";
// Allocate the query object.
myquery = new QSqlQuery( db );
myquery->clear();
myquery->exec("INSERT INTO phone_table(name_) VALUES ('asdhjs')");
db.close();
}
else
{
qDebug() << "Db is not connected!" << db.lastError();
}

Try this instead of your two myquery lines:
QSqlQuery q(db);
q.exec("INSERT INTO phone_table(name_) VALUES ('asdhjs')");

Related

QSqlQuery.next() return false but has data in database. Why?

I have data in my sqlite database. Insert statement executed successfully. But when want to get data from db i found nothing and this error "QSqlError("", "", "")". I have checked my query is active and not valid. How to solve this issue ?
Here is my code:
void FindDialog::find()
{
QString roll_number = ui->txt_RN->text ();
int roll = roll_number.toInt ();
const QString findstmnt = "SELECT Roll_Number, Name FROM student_info WHERE Roll_Number = :roll";
scon->getQuery ()->prepare (findstmnt);
scon->getQuery ()->bindValue ("roll", roll);
if(scon->getQuery ()->exec ()){
qDebug() << "Active: " << scon->getQuery ()->isActive ();
qDebug() << "Valid: " << scon->getQuery ()->isValid ();
if(scon->getQuery ()->isActive ()){
if(scon->getQuery ()->next ()){
qDebug() << "Has Data: " << scon->getQuery ()->next ();
} else {
qDebug() << scon->getQuery ()->lastError ();
}
}
} else {
qDebug() << scon->getQuery ()->lastError ();
}
The name of the parameter is not roll but :roll.
When you bind the value to the wrong parameter name, the actual parameter has its initial value, which is NULL.
So the query will never find any row because no value compares equal to NULL.

QNetworkAccessManager not emitting finished signal with this code

so i have been browsing the previous questions before about this issue, but i could not find a solution for my code.
cpp file of dialog
------------------------------------------------
#include "everesult.h"
#include "ui_everesult.h"
everesult::everesult(QWidget *parent) :
QDialog(parent),
ui1(new Ui::everesult)
{
ui1->setupUi(this);
}
everesult::~everesult()
{
delete ui1;
}
void everesult::setmodel(QStandardItemModel *model)
{
ui1->listView->setModel(model);
}
void everesult::on_buttonBox_clicked(QAbstractButton *button)
{
EveReprocess M_;
QModelIndex Selectedindex = ui1->listView->currentIndex();
QModelIndex StationIdsindex = ui1->listView->model()->index(0, 1);
int typeID = 0;
int stationID = 0;
stationID = ui1->listView->model()->data(StationIdsindex, Qt::DisplayRole).toInt();
typeID = ui1->listView->model()->data(Selectedindex, Qt::DisplayRole).toInt();
M_.GetMaterials(typeID, stationID);
}
--------------------------------------------------
Getmaterial and replyFinished from main window.
--------------------------------------------------
void EveReprocess::GetMaterials(int typeId, int stationid)
{
//get typeid from material list
this->modelMaterial = new QSqlQueryModel();
modelMaterial->setQuery(QString("SELECT tm.quantity, tm.materialTypeID, t.typeName FROM invTypeMaterials tm INNER JOIN invTypes t ON t.TypeID = tm.materialTypeId WHERE tm.TypeID=%1 ").arg(typeId));
if (!modelMaterial->query().exec())
qDebug() << modelMaterial->query().lastError();
//Set eve Central Url with typeids
QUrl url = QUrl("http://api.eve-central.com/api/marketstat?");
QUrlQuery q;
int numRows = modelMaterial->rowCount();
for (int row = 0; row < numRows; ++row)
{
QModelIndex index = modelMaterial->index(row, 1);
q.addQueryItem( QString("typeid"), QString::number(modelMaterial->data(index, Qt::DisplayRole).toInt()));
}
q.addQueryItem( QString("usesystem"), QString::number(stationid));
//set created url and connect
url.setQuery(q);
qDebug() << url;
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply *)));
manager->get(QNetworkRequest(url) );
}
void EveReprocess::replyFinished(QNetworkReply *reply)
{
qDebug() << "replyFinished called";
if ( reply->error() != QNetworkReply::NoError ) {
qDebug() << "Request failed, " << reply->errorString();
emit replyFinished(false);
return;
}
qDebug() << "Request succeeded";
//process with xmlreader and get values
processSearchResult( reply);
}
some of the code is here, i think it should be somewhere here, as the rest works fine.
this issue showed up after i use a dialog to let user pick a int from a list.
below is the function that calls the dialog that i have made for this. sorry about code format wil clean it up after it is working
void EveReprocess::Search_TypeId(QString ItemName, QString SystemName)
{
QList<int> TypeIdList;
QList<int> StationIdList;
modelIds = new QStandardItemModel(10,2,this);
if !(db.isOpen()) return;
this->queryItem = new QSqlQuery;
queryItem->prepare("SELECT typeID FROM invTypes WHERE invTypes.typeName LIKE ? AND invTypes.groupID NOT IN (268,269,270)AND published= 1");
ItemName.prepend("%");
ItemName.append("%");
queryItem->bindValue(0, ItemName);
this->queryStation = new QSqlQuery;
queryStation->prepare("SELECT solarSystemID FROM mapSolarSystems WHERE mapSolarSystems.solarSystemName LIKE ?");
SystemName.prepend("%");
SystemName.append("%");
queryStation->bindValue(0, SystemName);
if(!queryStation->exec() || !queryItem->exec() )
{
qDebug() << queryItem->lastError().text();
qDebug() << queryItem->lastQuery();
qDebug() << queryStation->lastError().text();
qDebug() << queryStation->lastQuery();
}
while( queryStation->next())
{
StationIdList.append(queryStation->value(0).toInt());
}
while(queryItem->next())
{
TypeIdList.append(queryItem->value(0).toInt());
}
for (int i = 0; i < StationIdList.count(); ++i)
{
modelIds->setItem(i,1,new QStandardItem(QString::number(StationIdList.at(i))));
}
for (int i = 0; i < TypeIdList.count(); ++i)
{
modelIds->setItem(i,0,new QStandardItem(QString::number(TypeIdList.at(i))));
}
//
everesult Dialog;
Dialog.setmodel(modelIds);
Dialog.exec();
}
Before you proceed any further, some of your code is allows SQL injections. Even when it's not a security hole, it'll still lead to bugs. Instead of using string substitution in SQL queries, you should be using bindings.
Your problem is here:
everesult Dialog;
Dialog.setmodel(modelIds);
Dialog.exec();
The exec() is a blocking function - it blocks the main event loop until the dialog is dismissed. Thus the signals from the threaded network access manager never get delivered to your objects.
You should display the dialog box asynchronously, like so:
everesult * dialog = new everesult;
dialog->setModel(modelIds);
dialog->show();
connect(dialog, SIGNAL(accepted()), dialog, SLOT(deleteLater());
connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater());
Note that it's misleading to have type names starting with lower case and variable names starting with upper case. Qt's convention is the opposite, and it's useful to retain it unless you have a good reason to do otherwise.
DO Parameter Binding in SQL Queries
QSqlQuery query("SELECT .. WHERE tm.TypeID=:typeid");
query.bindValue(":typeid", typeId);
QSqlQueryModel model;
model.setQuery(query);
DON'T DO String Substitution in SQL Queries
setQuery(QString("SELECT ... WHERE tm.TypeID=%1 ").arg(typeId));

QXmlQuery and XSLT20: Resultant Output String is empty everytime, works well on shell(xmlpattern)

I am writing a class to parse Itunes Libray File using QXmlQuery and QT-XSLT.
Here's my sample code:
ItunesLibParser::ItunesLibParser()
{
pathToLib = QString("/Users/rakesh/temp/itunes_xslt/itunes_music_library.xml");
}
void ItunesLibParser::createXSLFile(QFile &inFile)
{
if (inFile.exists()) {
inFile.remove();
}
inFile.open(QIODevice::WriteOnly);
QTextStream out(&inFile);
out << QString("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
out << QString("<xsl:stylesheet version=\"2.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">");
out << QString("<xsl:output method=\"text\" />");
out << QString("<xsl:template name=\"playlistNames\">");
out << QString("<xsl:value-of select=\"child::integer[preceding-sibling::key[1]='Playlist ID']\"/>");
out << QString("<xsl:text>
</xsl:text>");
out << QString("<xsl:value-of select=\"child::string[preceding-sibling::key[1]='Name']\"/>");
out << QString("<xsl:text>
</xsl:text>");
out << QString("</xsl:template>");
out << QString("<xsl:template match=\"/\">");
out << QString("<xsl:for-each select=\"plist/dict/array/dict\">");
out << QString("<xsl:call-template name=\"playlistNames\"/>");
out << QString("</xsl:for-each>");
out << QString("</xsl:template>");
out << QString("</xsl:stylesheet>");
inFile.close();
return;
}
void ItunesLibParser::dumpPlayList()
{
QXmlQuery query(QXmlQuery::XSLT20);
query.setFocus(QUrl(pathToLib));
QFile xslFile("plist.xsl");
createXSLFile(xslFile);
query.setQuery(QUrl("plist.xsl"));
QStringList* outDump = new QStringList();
query.evaluateTo(outDump);
if(outDump != NULL) {
QStringList::iterator iter = (*outDump).begin();
for (; iter != (*outDump).end();
++iter)
//code flow doesn't come here. It means being() == end()
std::cout << (*iter).toLocal8Bit().constData() << std::endl;
}
return;
}
OutDump here doesn't contain data. While in Shell (xmlpatterns-4.7 mystlye.xsl itunes_music_library.xml ), If I run my Query I get proper output.
Is there anything, wrong I am doing while calling it programatically? I checked out plist.xsl is created properly, but my doubt is whether "/Users/rakesh/temp/itunes_xslt/itunes_music_library.xml" this is getting loaded or not? Or there might be another reasons, I am confused. Is there any experts to throw some light onto problem, I will be glad.
Intead from reading from the file, I read the file into buffer and converted that int string as passed to setquery. That solved the problem.
Here's sample code for those who could face similar problem in future.
void ITunesMlibParser::parsePlayListItemXml(int plistId)
{
QXmlQuery xQuery(QXmlQuery::XSLT20);
QFile inFile("/Users/rakesh/temp/itunes_xslt/itunes_music_library.xml");
if (!inFile.open(QIODevice::ReadOnly)) {
return;
}
QByteArray bArray;
while (!inFile.atEnd()) {
bArray += inFile.readLine();
}
QBuffer xOriginalContent(&bArray);
xOriginalContent.open(QBuffer::ReadWrite);
xOriginalContent.reset();
if (xQuery.setFocus(&xOriginalContent))
std::cout << "File Loaded" << std::endl;
//..
//..
}
Thanks
Rakesh

Sqlite3 network oddity

I have a simple QT program to read an sqlite3 database. Annoyingly, my program failed when the actual database is on the network as a mapped drive (Windows 7) but works when the database is on the local drive. The code I'm using is below and just for experimental purposes.
QFileInfo fileInfo(m_lastDatabaseFile);
QString host = fileInfo.canonicalPath();
QString filename = fileInfo.fileName();
m_dataBase = QSqlDatabase::addDatabase("QSQLITE");
m_dataBase.setHostName(host);
m_dataBase.setDatabaseName(filename);
qDebug() << " valid: " << m_dataBase.isValid();
if (m_dataBase.open() )
{
QStringList tableList = m_dataBase.tables(QSql::Tables);
qDebug() << "Database open.";
QSqlQuery query = m_dataBase.exec("SELECT * FROM PallolBoards");
qDebug() << "Found: " << query.size();
if (query.size() <= 0)
{
QSqlError err = query.lastError();
qDebug() << "Last error: " << err.text();
}
while (query.next() )
{
QString title = query.value(0).toString();
qDebug() << "Query: " << title;
}
}
else
{
QMessageBox::critical(this,"Invalid database",m_dataBase.lastError().text());
}
Any clues anyone? So H: will fail but D: succeeds.
At least in windows vista there was a security setting controlling if an application was allowed to access network shares or not.
There is also a dependency between Internet security settings(accessible through e.g. internet explorer) and access to network shares.

QJSON using in Mac - getting some issues

I am using the QJson for parsing. But I am stuck up with some issues. I have used the following code:
void CityBook ::getCityList(QUrl url)
{
//!connect(cityReply, SIGNAL(readyRead()),this, SLOT(httpReadyRead()));
cityGuideNetworkAccessManager = new QNetworkAccessManager(this);
connect(cityGuideNetworkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(httpReadyRead(QNetworkReply*)));
QNetworkRequest cityRequest(url);
cityGuideNetworkAccessManager->get(cityRequest);
}
void CityBook::httpReadyRead(QNetworkReply *reply)
{
QMessageBox::information(this, tr("HTTP"),
tr(reply->readAll()),QMessageBox::NoButton
);
QJson::Parser parser;
bool ok;
const QByteArray &resultbyte = reply->readAll();
qDebug() << resultbyte;
QVariant result1 = parser.parse(reply->readAll(), &ok);
qDebug() << result1;
QVariantList result=parser.parse(resultbyte,&ok).toList();
qDebug()<< result.size();
if (!ok)
{
qFatal("An error occurred during parsing");
exit (1);
}
qDebug() <<"error String"<< parser.errorString();
qDebug() <<"error" <parser.errorLine();
//! QVariantList entries = result["name"].toList();
foreach (QVariant city, result) {
QVariantMap names = city.toMap();
qDebug() << "\t-" << names.value("name");
}
}
The output is:
Starting /Users/QT Developement/CityBook-build-desktop/CityBook.app/Contents/MacOS/CityBook...
""
QVariant(, )
0
error String ""
error 0
The result of the readAll function is an empty byte array. According to documentation this can mean either that no data are available or that an error occurred.

Resources