Why QSqlDatabase object won't work if addDatabase method assigned later? - c++

This won't work:
{
QSqlDatabase db;
db.addDatabase("QSQLITE", "manDb");
QString path = QDir::currentPath()+"/"+"Sqlite.db";
db.setDatabaseName(path);
if(db.open())
{
qDebug()<< "Database Created successfully...";
}else{
qDebug()<< "Failed to create Database...";
}
}
QSqlDatabase::removeDatabase("manDb");
Output: Failed to create Database...
But this works:
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "manDb");
QString path = QDir::currentPath()+"/"+"Sqlite.db";
db.setDatabaseName(path);
if(db.open())
{
qDebug()<< "Database Created successfully...";
}else{
qDebug()<< "sucessfully Failed to create Database...";
}
}
QSqlDatabase::removeDatabase("manDb");
Output: Database Created successfully...
Why?

Your first code sample does not work because according to documentation
QSqlDatabase db;
Creates an empty, invalid QSqlDatabase object. Use addDatabase(), removeDatabase(), and database() to get valid QSqlDatabase objects.
Then you try to call static QSqlDatabase::addDatabase method with db.addDatabase("QSQLITE", "manDb"); which returns QSqlDatabase class instance, but you do not assign it's return value to variable to use it later.
Adds a database to the list of database connections using the driver type and the connection name connectionName. If there already exists a database connection called connectionName, that connection is removed.
The database connection is referred to by connectionName. The newly
added database connection is returned.
So, in the first sample you tried to use QSqlDatabase in wrong way. Meanhile your second sample is a correct usage.

Related

I can't insert data into my sqlite3 database using qt 6

I have a test.db database on my project directory, which I'm trying to insert data into. The database is connected, but I can't seem to insert data in it. The query is not executed at all (it seems), since the qDebug shows "Bad".
QSqlDatabase connectDB(){
QSqlDatabase db= QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("test.db");
return db;
}
void planner::on_dataSend_clicked()
{
QSqlDatabase datba = connectDB();
if (datba.open()){
qDebug()<< "DB Suc";
} else{
qDebug() << "DB Fail";
}
QString what = ui->addPlan->text();
QSqlQuery qry;
qry.prepare("insert into plan values :what");
qry.bindValue(":what",what);
if (qry.exec()){
qDebug()<< "Good";
qry.clear();
} else{
qDebug()<<"Bad";
qDebug()<<qry.lastError();
qry.clear();
}
datba.close();
ui->addPlan->clear();
}
I'm using DB Browser for SQLite, and this is the database
The error that QSqlError shows is parameter count mismatch here
On SQLITE table, there is a default column as a primary key called rowid, you need to spécify the column that you want to add like this:
qry.prepare("insert into plan (column_name) values (:what)");

connection 'qt_sql_default_connection' is still in use, all queries will cease to work

I've made separate functions for open and close connection.But it wont let me to add new record on new form.
this is login header file.
public:
QSqlDatabase mydb;
void connClose()
{
//QString connection;
//connection = mydb.connectionName();
mydb.close();
//mydb.removeDatabase(connection);
mydb.removeDatabase(mydb.connectionName());
}
bool connOpen()
{
mydb=QSqlDatabase::addDatabase("QSQLITE");
mydb.setDatabaseName("./Poem.db");
if(mydb.open())
{
return true;
}
else if(!mydb.open())
{
return false;
}
}
this is the other form add button :
QString Title,Group,Poem;
Title = ui->lineEdit->text();
Group = ui->label_2->text();
Poem = ui->textEdit->toPlainText();
MainWindow mainwindow;
mainwindow.connOpen();
QSqlQuery * qry1 = new QSqlQuery(mainwindow.mydb);
qry1->prepare("insert into Poems(Title,Poem,Group) values ('"+Title+"','"+Poem+"','"+Group+"')");
if(qry1->exec())
{
QMessageBox::critical(this,tr("درج شعر جدید"),tr("شعر اضافه شد"));
mainwindow.connClose();
}
I get this errors :
duplicate connection name 'qt_sql_default_connection', old connection removed.
connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
You are committing exactly what Qt QSqlDatabase Documentation warns about:
Warning: There should be no open queries on the database connection
when this function is called
...
// WRONG
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
QSqlDatabase::removeDatabase("sales"); // will output a warning
// "db" is now a dangling invalid database connection, // "query"
contains an invalid result set
and the correct is:
{
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
}
// Both "db" and "query" are destroyed because they are out of scope
QSqlDatabase::removeDatabase("sales"); // correct
So in your case you execute query qry1 and remove the database within same scope (i.e before qry1 goes out of scope), you should modify your code to make sure qry1 is executed and gets destroyed / goes out of scope / before deleting the database. Try this:
{
QSqlQuery * qry1 = new QSqlQuery(mainwindow.mydb);
qry1->prepare("insert into Poems(Title,Poem,Group) values ('"+Title+"','"+Poem+"','"+Group+"')");
if(qry1->exec())
{
QMessageBox::critical(this,tr("درج شعر جدید"),tr("شعر اضافه شد"));
}
}
mainwindow.connClose();

cannot name connection in qt

QSqlDatabase db;
DBCONNECTION( QString conName)
{
db.addDatabase("QMYSQL",conName);
db.setDatabaseName("mitsubishi");
db.setHostName("localhost");
db.setUserName("root");
db.setPassword("");
qDebug()<<db.connectionName()<<conName;
}
db.connectionName returns empty string
but conName returns "string"
whats the problem?
and while executing query driver is not loaded
QSqlDatabase::addDatabase is a static function which returns a QSqlDatabase object. So it is not doing anything to your existing QSqlDatabase object. How you should use it:
db = QSqlDatabase::addDatabase("QMYSQL", conName);

Qsqlite duplicate connection warning in qt c++

I am creating an application in qt which uses sqlite database. I have written a class to open database connection. The constructor for the class is given below:
currencydb::currencydb()
{
currency = QSqlDatabase::addDatabase("QSQLITE");
currency.setDatabaseName("currency.sqlite");
if(!currency.isOpen())
{
if (!currency.open())
{
qDebug() << "Error: connection with database fail";
}
else
{
qDebug() << "Database currency: connection ok";
}
}
}
Since i use this constructor, when i create object for the database class, i get following warning:
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
Is there a way to check whether the database is already open?
That warning doesn't mean that your database is already open but that you already have a connection to the database with a default name. The connection provides access to the database via (in your case SQLITE v3) database driver. You create a default connection to the database when you don't pass the connection name argument when you call static public method QSqlDatabase::addDatabase().
You can use QSqlDatabase::contains() for checking if you already have the default connection.
CurrencyDb::CurrencyDb()
{
currency = openDb("QSQLITE", "currency.sqlite");
}
QSqlDatabase CurrencyDb::openDb(const QString &driver, const QString &name) const
{
QSqlDatabase db;
// contains() default argument is initialized to default connection
if (QSqlDatabase::contains())
{
db = QSqlDatabase::database(QLatin1String(QSqlDatabase::defaultConnection), false);
}
else
{
db = QSqlDatabase::addDatabase(driver.toUpper());
}
db.setDatabaseName(name);
if (!db.isValid())
{
// Log error (last error: db.lastError().text()) and throw exception
}
if (!db.open())
{
// Log error (last error: db.lastError().text()) and throw exception
}
return db;
}

SQLite remove database error

I have widget which connects to database:
Widget::Widget(QWidget *parent)
{
QString databaseName = "name";
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(databaseName);
db.setHostName("localhost");
if(!db.open())
qDebug()<<"ret error";
}
Now I want to delete database connection after widget close (currently I get warnings like: QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection is still in use...). I' ve read some topics and tried to evaluate some solution from them but none works for me. My code:
void Widget::closeEvent(QCloseEvent *e)
{
QSqlDatabase db = QSqlDatabase::database();
QString connection = db.connectionName();
db.close();
QSqlDatabase::removeDatabase(connection);
qDebug()<<"error: "<<db.lastError().text();
}
Error I get is: Driver not loaded Driver not loaded
What is the correct way to do this?
Edit:
another method:
void Widget::someMethod()
{
QSqlDatabase db = QSqlDatabase::database();
QSqlQuery query(db);
query.exec("some query");
}
Try giving a connection name parameter(2nd parameter) in addDatabase() , that should solve your problem.
Here is the modified code you could try:
Widget::Widget(QWidget *parent)
{
QString databaseName = "name";
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "test_db_connection" );
db.setDatabaseName(databaseName);
db.setHostName("localhost");
if(!db.open())
qDebug()<<"ret error";
}
Here is a complete working code from my machine for sqlite database which you can use as reference:
local_db = QSqlDatabase::addDatabase("QSQLITE","localdb");
local_db.setDatabaseName("localdb.sqlite");
local_db_query = QSqlQuery(local_db);
local_db_query.prepare( "SELECT * FROM sample_table" );
local_db_query.exec();