ODB 1.4.0 released
Wednesday, April 27th, 2011ODB 1.4.0 was released today.
In case you are not familiar with ODB, it is an object-relational mapping (ORM) system for C++. It allows you to persist C++ objects to a relational database without having to deal with tables, columns, or SQL, or manually writing any of the mapping code.
This version includes a number of major new features, small improvements, and bug fixes. For an exhaustive list of changes, see the official ODB 1.4.0 release announcement. As usual, below I am going to examine the most notable new features in more detail.
Qt profile
Two versions ago we announced the Boost profile. Now it is Qt’s turn. As you may remember, ODB profiles are a generic mechanism for integrating ODB with widely-used C++ frameworks and libraries. A profile provides glue code which allows us to seamlessly persist various components, such as smart pointers, containers, and value types found in these frameworks and libraries.
In this initial release the Qt profile covers the most commonly used basic types (QString
and QByteArray
), date-time types (QDate
, QTime
, and QDateTime
), smart pointers (QSharedPointer
and QWeakPointer
plus their lazy variants, QLazySharedPointer
and QLazyWeakPointer
), and containers (QVector
, QList
, QLinkedList
, QSet
, QMap
, QMultiMap
, QHash
, and QMultiHash
). For example, now we can write:
#pragma db object class Employee { ... QString first_name_; QString last_name_; QDate born_; QSet<QString> emails_; QByteArray publicKey_; QSharedPointer<Employer> employer_; };
As is evident from the code fragment above, we don’t need to do anything special to use Qt types in our persistent classes. All we need are these three simple steps:
- Download and build the Qt profile library,
libodb-qt
- Specify the Qt profile when invoking the ODB compiler. For example:
odb -d mysql --profile qt employee.hxx
- Link the profile library to your application.
And that’s it. That’s all we need to do. For more detailed information on ODB profiles in general, refer to Chapter 13, “Profiles Introduction” in the ODB Manual. For more information on the Qt profile, see Chapter 15, “Qt Profile”.
Inheritance
ODB now supports persistent class inheritance. In this version only non-polymorphic, reuse-style inheritance is supported with each class mapped to a separate database table that contains all the data members, including those inherited from base classes.
It is now also possible to declare a persistent class abstract. Instances of such a class are not stored in the database. Rather, it is used as a base for other persistent classes. For example:
#pragma db object abstract class person { ... std::string first_; std::string last_; }; #pragma db object class employee: public person { ... #pragma db id auto unsigned long id_; }; #pragma db object class contractor: public person { ... #pragma db id std::string email_; };
For the above example the database schema will contain only two tables, employee
and contractor
, with the following definitions:
CREATE TABLE employee ( first TEXT NOT NULL, last TEXT NOT NULL, id BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT); CREATE TABLE contractor ( first TEXT NOT NULL, last TEXT NOT NULL, email VARCHAR (255) NOT NULL PRIMARY KEY);
For more details on inheritance, refer to Chapter 8, “Inheritance” in the ODB Manual as well as the inheritance
example in the odb-examples
package. Support for polymorphic inheritance is coming in future versions of ODB.
C++ enum
mapping
ODB can now automatically map C++ enumerations to suitable database types. Let’s say we define C++ type color
like this:
enum color {red, green, blue};
If we are targeting the MySQL database, which supports ENUM
SQL type, then color
will be automatically mapped to ENUM('red', 'green', 'blue')
. If the target database does not support enumerations, such as SQLite, then the ODB compiler will map color
to a suitable integer type.
It is also easy to override this mapping. Let’s say we always want to store color
as an integer, even in databases such as MySQL. Then we can specify the desired type explicitly:
#pragma db value type("INT UNSIGNED") enum color {red, green, blue};
Or, maybe, our convention is to capitalize the enumerators in the database. We can do that as well:
#pragma db value type("ENUM ('RED', 'GREEN', 'BLUE')") enum color {red, green, blue};
There are also other important features in this release, including, the new id_type
pragma and consistent size_t
type mapping. Refer to the official ODB 1.4.0 release announcement for more details on these and other features.