TinyDrivers: Getting Started
Introduction​
Stability: 2 - Stable
The TinyDrivers
library is an underlying SQL database layer for TinyORM
. It can be used instead of the QtSql
module, can be swapped at compile time, and has 1:1 API as the QtSql
module. 😮 Swapping is controlled by the qmake
and CMake
build system options.
It was designed to drop the QtSql
dependency while maintaining backward compatibility and without the need for any code changes after the swap.
Features summary​
- both, normal and prepared statements are supported
- TLS/SSL connections using
MYSQL_OPT_SSL_MODE
(verify_ca, verify_identity) 🔥 - setting many other MySQL connection options (see
mysqldriver_p.cpp
) - building and linking against the
MariaDB Connector/C
🕺 - transactions
- re-using the current
SqlQuery
instance to re-execute the same or another SQL query - detaching from the result set (related to freeing/releasing memory)
- query size, number of affected rows, last inserted ID, testing
isNull()
, ... - all 3378 unit tests passed 😮
- strictly using smart pointers (no
new
keyword in the wholeTinyDrivers
code base 😎) - clear code 🤔
Currently, only the MySQL
database driver is supported and finished. 😞
TinyDrivers
library supports both build systems qmake
and also CMake
.
Differences from QtSql​
TinyDrivers
doesn't return errors the the same way as the QtSql
module, which means return a bool
and if it's the result false
then obtain the SqlError
instance using the lastError()
method from SqlDatabase
or SqlQuery
instances. Instead, it throws exceptions, and methods returning a bool
type to report an error state always return true
.
Naming conventions​
QtSql
module ->TinyDrivers
libraryQMYSQL
driver ->TinyMySql
driver
MySQL driver​
The following describes the differences between QMYSQL
and TinyMySql
drivers.
The QMYSQL
driver doesn't support setting MySQL
non-flag connection options like MYSQL_OPT_RECONNECT
without the value, it needs to be defined with value like =1
or =TRUE
(case-sensitive), only real flag options like CLIENT_INTERACTIVE
can be set without the value and =
character.
On the other hand, the TinyMySql
driver allows setting non-flag connection options options without the value and =
character, which are considered enabled (ON or TRUE).
Removed features​
Simulation of prepared statements while calling SqlQuery::exec(QString)
, this functionality is useless because you can call regular prepared statements using SqlQuery::prepare(QString)
and then SqlQuery::exec()
.
Missing features​
Fetching multiple result sets using SqlQuery::nextResult()
. Multiple statement queries are supported they will be executed correctly (they can return multiple result sets), but only the first result set can be fetched currently. However, destroying multiple result sets is handled correctly.
Build system​
Another difference is that you can build the TinyDrivers
and its SQL drivers (TinyMySql
) in 3 different ways; Shared
, Static
, and as a Loadable
library at runtime using LoadLibrary()
on Windows or dlopen()
on Linux.
The Shared
library build​
It builds two shared libraries, the TinyDrivers
shared library that contains the core/common code and the TinyMySql
shared library that contains MySQL
implementation. The TinyOrm
links only against the TinyDrivers
shared library and TinyMySql
is a private implementation.
The Static
build​
It builds one TinyDrivers
static archive that contains the core/common code and SQL drivers (TinyMySql
). This static library is linked or merged into the TinyOrm
shared or static library (both variants are supported).
The Loadable
SQL drivers build​
It builds two shared libraries, the TinyDrivers
shared library that contains the core/common code and TinyMySql
shared library (module) that contains MySQL
implementation that is loaded at runtime using LoadLibrary()
on Windows or dlopen()
on Linux. The SQL driver library loader throws an exception if it cannot find this library at runtime.
The TinyMySql
links directly against the MySQL C connector
(libmysql
or mysqlclient
library).
CMake
/qmake
build options​
For CMake
​
See CMake build options, related CMake
build options are:BUILD_DRIVERS
, BUILD_MYSQL_DRIVER
, and DRIVERS_TYPE
To control shared and static build use BUILD_SHARED_LIBS
CMake
configuration option.
For qmake
​
See qmake build options, related qmake
configuration options are:build_loadable_drivers
, build_mysql_driver
, build_shared_drivers
, and build_static_drivers
To control shared and static build use static
qmake
configuration option.
Performance​
Performance is several milliseconds faster compared to QtSql
with the QMYSQL
driver. It was tuned using the KCacheGrind
to be so. It's ~40ms faster on TinyOrmPlayground
project with 620 database queries compiled using GCC v13.2.1
Debug build on Linux. Similar results can be expected on other platforms but it's not guaranteed.
This means performance is very similar to QtSql
. There is not much to speed up because TinyDrivers
code is swift and 90% of the time is spent inside the MySQL C API
because we always have to wait for the database server, especially when creating database connections using eg. mysql_real_connect()
(this function is king among the slowest functions 😎, which is understandable of course).
Internals​
TinyDrivers
internal design can be divided into 3 different layers:
- Driver layer
- SQL API layer
- Public API layer
The Driver layer is eg. TinyMySql
library which is responsible for communicating with the underlying database driver (eg. MySQL C API
).
The SQL API layer is a semi-layer that glues everything up and sits between the Public interface API and the Driver layer.
The Public interface API layer are the end classes like SqlDatabase
and SqlQuery
which are exposed to the end user.
SqlDatabase​
One more thing worth mentioning is the SqlDatabase
API. It's one class that has two responsibilities! All static methods act as the database connection manager and an instance of the SqlDatabase
represents a physical database connection. It's not a good design because it breaks the Single Responsibility principle, but it's what it is.
Namespaces​
TinyDrivers
classes are defined in the Orm::Drivers
namespace and TinyMySql
classes in the Orm::Drivers::MySql
namespace.
Documentation​
For all other APIs you can follow the QtSql documentation as the API is 1:1. The exception is of course the build system, TinyOrm
has its own build system that doesn't follow the QtSql
module.