0

I need to store a QRect in an Sqlite database. (I've searched around but did not see anything on this)

Does Qt/QSQLITE automatically convert QRect to a QVariant and handle whatever decomposition is needed or do I have to do this myself and store the origin and size values in four separate fields?

If so, and to generalize this to other Qt data types, is it possible to store QVector, QList? Would I define these (and QRect, etc.) as BLOB types in my table definitions?

spring
  • 18,009
  • 15
  • 80
  • 160
  • I'd read the raw bytes of the rect (members are sequential in memory), store in the DB as string, then just copy the string back into the memory address of a rect to do a quick binary "initialization". – dtech Aug 12 '13 at 19:53

3 Answers3

5

SQLite is a relational database and those things cannot store C++ objects directly.

Actually the C++ object model doesn't allow a fully transparent persistence but you can try to get somewhat close using specialized tools or libraries. The important point is however that the objects themselves must be designed to support persistence.

If you don't need transparent persistence but only explicit store/retrieval of objects then you can just pick up a serialization method you like (e.g. using a single string, or using separate fields for the attributes). Each method has pros and cons depending on what you want to do with the database (e.g. what kind of searches or updates you want to do).

Something that is also unfortunate about C++ is that its metaprogramming abilities are very poor (just a little better than C) and for example introspection is impossible.

This means that you will need to write your serialization code for each class that you will need to support or you will need to find/buy an external tool that looking at the class definition .h will generate the needed code for you. It must be an external tool because serialization is something that is outside the very limited reach of template metaprogramming.

Qt itself already has some specialized serialization machinery QDataStream so may be you can use that for what you are looking for: for example QRect is serializable and QList<T> is serializable if T is.

Using that would require to serialize to a QByteArray first and then store the blob inside SQLite. For example after writing

template<typename T>
QByteArray serialize(const T& x)
{
    QByteArray ba;
    QDataStream s(&ba, QIODevice::WriteOnly);
    s << x;
    return ba;
}

template<typename T>
T deserialize(QByteArray& ba)
{
    QDataStream s(&ba, QIODevice::ReadOnly);
    T res; s >> res;
    return res;
}

you can serialize an object directly to a QByteArray with

QByteArray ba = serialize(x);

and you can deserialize it with

X x = deserialize<X>(ba);
6502
  • 112,025
  • 15
  • 165
  • 265
  • Thanks. I'm new to Qt and have been working with Objective-C for iOS where there are built-in conversion methods for these sorts of reqs. (e.g. `NSStringFromCGRect`, `CGRectFromString`) and `NSManagedObjects` for database storage. Hadn't seen anything like this in Qt. – spring Aug 12 '13 at 19:54
  • @TOMATO: With Qt serialize machinery you can get something similar by writing a couple of templates, one that given any serializable object instance (e.g. a `QList`) gives you back a `QByteArray` and another that given a `QByteArray` and the type gives you back an instance. See edit. – 6502 Aug 12 '13 at 21:28
1

You could store QRect in a different table which will have (for example) id, x, y, h, w as columns.

When you want to store QRect, create new row in newly created table, get its id and store it inside destination table.

QVector and QList are containers, where QRect is a simple struct. You could save it in a separate table (one row for each entry), or you could just serialize the container and save it inside BLOB column.

Community
  • 1
  • 1
Nemanja Boric
  • 21,627
  • 6
  • 67
  • 91
0

No, you have to do it yourself. How you store your QRect into Sqlite is up to you and your requirements. Storing the individual values, serializing the whole data type into a TEXT, BLOB or whatever using QDataStream... what ever fits you best.

Greenflow
  • 3,935
  • 2
  • 17
  • 28