Added the test case which tests returning
the std::unique_ptr<Relation<>> instead of the derived relation
eg. std::unique_ptr<HasMany> from the relationship factory methods.
This behavior is considered an additional feature and is possible
thanks to the polymorphism.
The Orm::Tiny::Types::ModelsCollection is container class with
additional handy methods like pluck(), whereIn(), filter(), ...
It extends the QVector. The template parameter can be the Model or
Model *, the model must be the Derived model type eg. Torrent, Post, ...
All ORM-related methods return the ModelsCollection so it can be easily
filtered, changed, transformed with one simple line or callback.
All the algorithms are nicely encapsulated in the ModelsCollection
methods.
Currently, there is this pattern, all TinyBuilder or Model methods are
returning the ModelsCollection<Derived> and all relation related
methods are returning the ModelsCollection<Derived *>.
- added Album and AlbumImage migrations and seeder data (also PHP)
- added Album and AlbumImage models
- added functional tests for ModelsCollection<Model> and
ModelsCollection<Model *>
- all ModelsCollection methods or algorithms are unit tested
- replaced all occurences of the QVector<Model> and QVector<Model *>
with the ModelsCollection<Model> and ModelsCollection<Model *> 😵💫
- tests added Model::findMany()
- added reserve() on few places
- removed useless #include-s
- primarily fixed instantiation with Default Attribute values with
the QDateTime
- revisited ctors and instance methods
- added instanceHeap methods, create model instance on the heap
- added instance method overloads with the connection override param.
- added tests for all these new and old methods and ctor-s
- used Model::instance() related methods all over the TinyORM to
correctly support Model instantiation with Default Attribute values
with the QDateTime
- added a new Model constructor with the DontFillDefaultAttributes tag
that instantiates a Model class without fill default attributes, to
bypass CRTP problem with the QDateTime; this ctor is called from
the instance()-related methods and the fill() method is called on
already instantiated Model
methods
- updated NOTES.txt where the raw Model ctor-s were called
Fixed buggy behavior of QDateTime values during SELECT, INSERT, and
UPDATE queries for all supported QtSql drivers. Behavior is fixed if
querying the database using Orm::QueryBuilder or TinyBuilder/Model.
Can't be fixed if using raw queries using the QSqlQuery because I don't
have any control over this code.
Every QtSql driver behaves differently in how it works with
the QDateTime and datetime-related database types. It doesn't have only
one problem, it has various kinds of problems, eg. it returns all
QDateTime objects in the local time zone. All issues are summarized
in NOTES.TXT under "QDateTime and database date/time types:"
section.
This buggy behavior can be fixed or corrected using a new "qt_timezone"
database connection configuration option. It accepts the time zone value
in various formats (QTimeZone, Qt::TimeSpec, int number as an offset
from UTC, QString eg. +02:00, Europe/Prague or Orm::QtTimeZoneConfig).
This "qt_timezone" value affects how the QueryBuilder and TinyBuilder
send and receives datetime-related types to/from database. It should be
set to the same time zone value as the "timezone" connection
configuration option.
During the INSERT and UPDATE statements, it CONVERTS QDateTime's
time zone to the qt_timezone value before the statement is sent
to the database.
And during the SELECT statements it SETS QDateTime's time zone value
after the values are obtained from the database.
So if you set the "timezone" to UTC and "qt_timezone" to eg. Qt::UTC or
QTimeZone::utc(), then QDateTime values will have set the correct
time zone, in this case, the time zone will be UTC.
For the SQLite database was also added the "return_qdatetime" connection
configuration option which default value is true. By default,
the QSQLITE driver returns datetime values as QString.
The "return_qdatetime" controls this behavior and if is set to true then
the QDateTime will be returned instead.
TinyORM QueryBuilder returns the Orm::SqlQuery instead of QSqlQuery
from methods for which the QDateTime's time zone should be corrected.
That are eg. the select(), selectOne(), unprepared(), or chunk(),
chunkById(), each(), eachById(), ...
Orm::SqlQuery is a simple wrapper around the QSqlQuery whose
responsibility is only to fix a QDateTime's time zone.
Also unified the QDate behavior across all QtSql drivers.
- added a new migration for the datetime table for testing QDateTime
and datetime-related database types
- added new Datetime model
- added functional tests for testing datetime-related queries
- testing QDateTime for all supported drivers
- testing with different time zones, UTC, +02:00
- testing QDate for all supported drivers
- added two new connection configuration options "qt_timezone" and
"return_qdatetime" which is for the SQLite database only
- added returnQDateTime()/setReturnQDateTime() getter/setter
to the SQLiteConnection class
- added getQtTimeZone()/setQtTimeZone()/isConvertingTimeZone()
to the DatabaseConnection class
- tests, fixed all QDateTime instances, changed time zone to UTC, so
auto tests are now UTC, they force also MySQL and PostgreSQL server
time zone session variable to UTC
Others:
- StringUtils moved from orm/tiny/utils/ to the orm/utils/ folder
to the ::Orm::Utils namespace
- enhanced all database connection constructors, used rvalue references
- added delegated DatabaseConnection() constructor
for SQLiteConnection() because of m_returnQDateTime
Attribute casting allows converting TinyORM Model attribute values when
you retrieve them on model instances. Conversion is done using
the QVariant::convert(QMetaType) method.
To cast attributes you can provide the Model::u_casts data member
of the type std::unordered_map<QString, CastItem>.
The CastItem type can be initialized by the CastType (first argument)
and optionally a modifier of the QVariant type (second argument).
Currently, only the CastType::Decimal accepts a modifier that rounds
the decimal number to the given number of decimals.
Supported Orm::Tiny::CastType-s are:
Bool, Boolean, Short, UShort, Int, Integer, UInt, UInteger, LongLong,
ULongLong, Real, Float, Double, Decimal, QString, QDate, QDateTime,
Timestamp, QByteArray.
The MySQL, PostgreSQL, and SQLite QSqlDriver-s already do conversions,
but every one of these drivers is doing these conversions in their own
way, only the varchar or text database types are handled uniformly.
The rules of how these Qt drivers are handling or converting these types
are not simple and the explanation will need it's own paragraph in docs.
Attributes casting is especially useful with the QSQLiteDriver. Other
useful use cases are casting of dates or Unix timestamps,
bool (tinyint), and the decimal type (also supports modifier).
- added functional tests
- added a new Type model class used by unit testing
- added a new migration and seeder for the Type model
- added showcase example to the Torrent model class
- updated Model::newInstance() method to also copy a model casts
- added TinyBuilder::withCasts() method to apply query-time casts
to the model instance
- added withCasts() model and relation proxies
- added functional tests for withCasts() (for all proxies 😎)
- set the u_casts for the boolean columns/attributes on RoleUser,
Tagged, and User models
User can define the u_table data attribute on a Custom Pivot model,
it has higher priority than the guessed table name
in the HasRelationships::pivotTableName().
Also fixed BasePivot::getTable(), it didn't return correct results.
The Model::u_dateFormat now also accepts 'U' for unix timestamps.
The database column type should be qint64 or int.
- added extensive unit tests also for null values, for getAttribute()
and also for setAttribute()
- updated migrations, added a new added_on unix timestamp column
to the Role model
- updated database seeders
- updated docs
In addition to actually removing records from your database, TinyORM
can also "soft delete" models. When models are soft deleted, they are
not actually removed from your database. Instead, a deleted_at attribute
is set on the model indicating the date and time at which the model was
"deleted".
- added docs
- added all proxies
- added complete functional tests and a few unit tests
- carefully verified all possible scenarios because it changes
practically all queries 🤯
Others:
- also added from() to all proxies
- bugfix in seeders, bad ID in the PostgreSQL primary key (sequence)
Database connection can run in a thread, if you create a connection in
a thread, then you have to use it only from that thread, moving it to
another thread is disallowed.
All restrictions for QSqlDatabase are true also for TinyORM.
The most important work was in DatabaseManager because more threads can
access it at once.
DatabaseManager has to be created only once in the whole application,
so it means when it will be created in a non-main thread, then it has
to be used from this non-main thread the whole time, I didn't try it
to move to another thread, the conclusion is that DatabaseManager can be
created and used from a worker thread.
- refactored db configuration
- added DatabaseConnectionsMap to outsource ConnectionsType and make it
thread_local
- added resetDefaultConnection()
- m_queryLogId is atomic
- made all class static data members thread_local
Thread unrelated:
- added two new addConnections() overloads
- added Thread utils class
- added NameThreadForDebugging()
- enhanced tst_DatabaseManager