PDA

View Full Version : question about QSqlDatabase and how to make query...



abdol
4th July 2011, 02:44
Hi everyone :),
I want to make a database query...
when I implement a class like:


class IntrfcDB
{
public:
IntrfcDB();
~IntrfcDB();
QSqlDatabase db;
QSqlQueryModel qry;

void useDBConn();
}

void IntrfcDB::useDBConn()
{
qry.exe("select * ...");
}

I get the message: database is not open.
If I rewrite my code like



class IntrfcDB
{
public:
IntrfcDB();
~IntrfcDB();
QSqlDatabase db;

void useDBConn();
}

void IntrfcDB::useDBConn()
{
QSqlQueryModel qry;
qry.exe("select * ...");
}


everything works perfectly (I initialize the connection in the constructor which uses the default connection).
I am new to both c++ and qt. I know that QSqlDatabase is a static function.
I would like to know is it possible to do such thing using the first method? and how?
If not, is this because of static function QSqlDatabase::addDatabase?
Is there anyone to give some explanation :confused: Thank you all :)

ChrisW67
4th July 2011, 05:59
The problem here is generic C++ understanding.

In your first example the qry object is default constructed during creation of the IntrfcDB object before your IntrfcDB constructor code is executed. At this time there is no database open, so the QSqlQueryModel (QSqlQuery) default constructor gets no valid result when it looks for the default db connection.

In your second example the qry object is not constructed until you call useDBConn() by which time you have set up a default database connection.

For some members you can give them an initial value in the constructor initialization list (http://www.cprogramming.com/tutorial/initialization-lists-c++.html) (before the constructor code) but this is not generally possibly with objects requiring multiple setup steps like QSqlDatabase. To keep it in the constructor you can allocate the QSqlQueryModel on the heap after creating the connection. You will ultimately need a pointer to the model for most functions that use it anyway.

abdol
4th July 2011, 16:58
Thanks a lot ChrisW67 (many times :))
I understood the firs part of your answer but I can't digest the 2nd part of it:


To keep it in the constructor you can allocate the QSqlQueryModel on the heap after creating the connection. You will ultimately need a pointer to the model for most functions that use it anyway.

do you mean that I have to create a pointer to QSqlDatabase and then new it in constructor? I will try it to see if I interpreted your answer correctly.
Thank you again.

ChrisW67
4th July 2011, 22:45
No, you need a pointer to the model for (almost) everything that needs to use a model. So, create the model on the heap (using new) and keep the pointer in the IntrfcDB object rather than an actual instance of QSqlQueryModel. The model is not constructed until you call new, which you can place after the database is set up.


class IntrfcDB: public QObject
{
Q_OBJECT

public:
IntrfcDB();
~IntrfcDB();
QSqlDatabase db;
QSqlQueryModel *qry;

void useDBConn();
}

IntrfcDB::IntrfcDB(): qry(0)
{
db = QSqlDatabase::addDatabase(...);
... other db init

qry = new QSqlQueryModel(this);
}

void IntrfcDB::useDBConn()
{
qry->exec("select * ...");
}

I have used QObject to manage deallocation but you could do it manually in the class destructor.