I am willing to store objects in a database. The purpose is to be able to read / write these objects with the program. The requirements are the following:
QList
, QString
... or even can contain other objects that use QObjects
I asked a question here, to do this with a QDataStream
with a minimalist example. But it seems it is not the best way to proceed.
Would you have some suggestions regarding the solutions that exist for this purpose?
I have tried the following but it does not fulfill the requirements:
QtSQL
: but the data is accessible by using sqlitemanager for example, can be modified or removed by humans. Moreover, I have no idea regarding the way to store QList
for example or other objects that I created and contain QObject
(for example, 2 QList
)QDataStream
: in this case, I cannot count the number of objects in my file, neither read or remove a specific object without loading the entire file in memory.I would be grateful if you could give me some suggestions or provide example, even if the example is minimalist.
I finally found a solution, especially thanks to Igor Tandetnik and thanks to the topic here
I haven't quite finalized, there is a small imperfection because I have to define an object of my user class that I don't use in order to call the readFromDB function to generate my object from the db.
On the other hand, I get this error message "QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed" each time I call my database.
Anyway, it's a bit late now, and I think it might help some people so I post this minimalist imperfect code below. I'll post an update in the next few days.
Thanks again.
#include "QString"
#include "QFile"
#include "QDataStream"
#include "qdebug.h"
#include "QtSql"
#include "QSqlDatabase"
#include "qmessagebox.h"
class User
{
protected:
QString name;
QList<QString> childrens;
public:
QString getName(){ return name;}
QList<QString> getChildrens(){ return childrens;}
void setName(QString x) {name = x;}
void setChildrens(QList<QString> x) {childrens = x;}
friend QDataStream &operator<<(QDataStream &out, const User &t)
{
out << t.name << t.childrens;
return out;
}
friend QDataStream &operator>>(QDataStream &in, User &t)
{
QString inname;
QList<QString> inchildrens;
in >> inname >> inchildrens;
t.name = inname;
t.childrens = inchildrens;
return in;
}
QByteArray object2blob( const User& user )
{
QByteArray result;
QDataStream bWrite( &result, QIODevice::WriteOnly );
bWrite << user;
return result;
}
User blob2object( const QByteArray& buffer )
{
User result;
QDataStream bRead( buffer );
bRead >> result;
return result;
}
int saveToDB( const User& user )
{
QSqlDatabase myDB = QSqlDatabase::addDatabase("QSQLITE");
myDB.setDatabaseName( "file.db");
if (!myDB.open())
{
qDebug()<<"Failed to open SQL database of registered users";
}
else
{
qDebug()<<"Successfully opening SQL database of registered users";
QSqlQuery query;
query.prepare( "CREATE TABLE IF NOT EXISTS users (name TEXT, childrens BLOB)" );
if( !query.exec() )
{
qDebug() << query.lastError();
}
else
{
qDebug() << "Table created!";
query.prepare( "INSERT INTO users (name,childrens) VALUES (:name,:childrens)" );
query.bindValue(":name", name);
query.bindValue( ":childrens", object2blob(user) );
query.exec();
}
query.clear();
myDB.close();
}
QSqlDatabase::removeDatabase("UserConnection");
return 0;
}
User readFromDB( QString name )
{
User result;
QSqlDatabase myDB = QSqlDatabase::addDatabase("QSQLITE");
myDB.setDatabaseName( "file.db");
if (!myDB.open())
{
qDebug()<<"Failed to open SQL database of registered users";
}
else
{
QSqlQuery query;
query.prepare( "SELECT * FROM users WHERE name ='"+ name +"'" );
//query.bindValue( 0, name );
if ( query.exec() && query.next() ) {
result = blob2object( query.value( 1 ).toByteArray() );
}
query.clear();
myDB.close();
}
QSqlDatabase::removeDatabase("UserConnection");
qDebug()<<result.getChildrens();
return result;
}
};
////////////////////////////////////////////////////////////////
int main()
{
User u;
u.setName("Georges");
u.setChildrens(QList<QString>()<<"Jeanne"<<"Jean");
u.saveToDB(u);
User v;
v.setName("Alex");
v.setChildrens(QList<QString>()<<"Matthew");
v.saveToDB(v);
User w;
w.setName("Mario");
w.saveToDB(w);
User to_read; //to improve here
User a = to_read.readFromDB("Georges");
qDebug()<<a.getChildrens();
return 0;
}