Moved all features which aren't used through CONFIG+=xyz and are loaded
using the load(private/xyz) function to the qmake/features/private/
folder.
Currently, the qmake/features/ folder contains only features which
should be used using the CONFIG+= qmake variable.
This is part 2 of: used TinyDrivers exceptions everywhere.
The Drivers::SqlError was dropped and renamed to DummySqlError which
does nothing and it exists only for API compatibility with QtSql module
and it also helps to avoid #ifdef-s in users/client code.
There are 3 exceptions (what is all this about) and they are SqlError,
QueryError, and SqlTransactionError. The SqlError is a general SQL
exception class that is thrown eg. during connecting to SQL server
or during all other SQL API calls that are not database queries or
transaction queries.
The second part of this commit was to modify all error handling
in TinyOrm library and adapt it to exceptions thrown from
the TinyDrivers library.
Many #ifdef-s were added because of this because QtSql module returns
bool and then you need to obtain the QSqlError and TinyDrivers library
throws exceptions.
This commit was huge, also it's very weird and this error handling
things are unpopular and everybody has different opinion on this, but
it is what it is.
There is not way I would return bool and set error state instead of
exceptions in TinyDrivers, never.
Also, there is no way I would catch Drivers::SqlError/QueryError/
SqlTransactionError in TinyOrm library and translate these TinyDrivers
exceptions to TinyOrm exceptions with the same names to throw only one
set of exceptions, no way. TinyDrivers throws its own exceptions and
TinyOrm linked against QtSql throws its own exceptions (with the same
names but in different namespace).
- removed all setLastError() and throw exceptions instead
- added new constants
- optimized #include-s
- changed the causedByLostConnection() method signature
- enhanced the ManagesTransactions class
- extracted code to the mysqlClose()
- removed MySqlDriverPrivate::q_ptr (not needed anymore)
- removed createError() and createStmtError() (not needed anymore) and
added prepareMySqlError() and prepareStmtError() as counterparts
- renamed method to errorMessageForStmtFetch()
- extracted the replaceBindingsInSql() because it's used from both
TinyOrm and TinyDrivers libraries
- enhanced replaceBindingsInSql()
- added support for BLOB-s
- the SqlError, QueryError, and SqlTransactionError are excluded from
TinyOrm library build and include path if compiled against
the TinyDrivers library (they are not needed and used anymore)
- added connection name to SqlResult class, it's used in exception
messages
- also updated auto tests
bugfix-es:
- qmake propagate the TINYDRIVERS_MYSQL_DRIVER DEFINE (made it public),
cmake build is OK
- removed mysql_thread_init()
- changed call order for the mysql_thread_end()
- and also to the tom --version
- added components to Dependencies section
- prints info also about TinyMySql
- takes into account all build types static/shared/loadable
- tests both build systems qmake/CMake
These Appends are appended to the serialized models during the toMap(),
toVector(), or toJson() methods call.
Appends names are and must be mapped using the u_mutators hash map
(in the same way like u_relations) because c++ doesn't support advanced
reflection.
Appends are mapped to methods (can be protected) that return
the Casts::Attribute. This Casts::Attribute is a wrapper to return
a new attribute value.
Appends accept u_visible and u_hidden.
For the Appends that return QDate or QDateTime are the counterpart
serializeDate() or serializeDateTime() methods called.
- added unit tests
A user can define the u_visible and u_hidden std::set static data
member for visible and hidden attributes on his models and they will be
used during serialization.
The relationships and also u_snakeAttributes are correctly taken into
account.
- added unit tests
- added example to Models::Torrent
The big HasRelationStore class with nested classes is finally divided
into smaller pieces, every store is in its own file in the Support NS.
Performance is the same as the old code, thanks god. 🙏
mt new: 564
mt old: 565
st new: 959 294
st old: 959 305
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
Changed from the 'schema' configuration option to the 'search_path',
the 'schema' config. option was dropped and currently throws exception
with a suggestion to use the 'search_path' instead.
The new 'search_path' config. option can be the QString or QStringList
and also supports to set an empty search_path using '' or empty QString
or QStringList.
This search_path config. option is correctly parsed and quoted.
Setting the search_path is initiated from the PostgresConnector
right after the database connection is established.
The PostgresSchemaBuilder is actively using the search_path during
practically all method calls (dropAllTables(), getColumnListing(),
hasTable(), ...). If the search_path is not defined then it queries
the database for the real search_path because the search_path can be
changed anytime and the search_path configuration option value can be
incorrect (out of sync).
It also works correctly with the empty search_path, in this case a fully
qualified table names are required. If the table name is not fully
qualified then the SearchPathEmptyError exception is thrown.
And it also works correctly with the "$user" PostgreSQL's variable, this
variable is resolved to the config["username"] during obtaining
the search_path from the database.
In the pretend mode it behaves little different, if pretending then
the 'search_path' is obtained from the connection configuration and
if the 'search_path' is not defined in the config. the 'public' will
be used as the default.
- added many new unit and functional tests which are testing all the
above described scenarios
- added new functional test case tst_PostgreSQL_SchemaBuilder_f
- added new functional test case tst_SchemaBuilder
- added new tests for dropAllTable(), dropAllViews(), hasTable(),
getColumnListing(), createDatabase(), dropDatabaseIfExists()
for ALL supported databases
- added new search_path constant
- renamed env. variable to DB_PGSQL_SEARCHPATH (from DB_PGSQL_SCHEMA)
- added new search_path and dont_drop configuration validations to
check correct type (QString or QStringList)
- added new 'schema' config. option validation
- added new exception SearchPathEmptyError
- started the TinyUtils::Databases refactor
- extracted logic to own classes
- every driver has it's own class and can have driver-specific logic
- the 'options' option has it's own parser class, is declared as
the mixin class
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
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)
It allows comparing a related model without issuing a query to retrieve
that model.
- added functional tests for both HasOne and also BelongsTo relations
- added docs
Others:
- added the new unit test case tst_Relations_Connection_Independent
The MySQL >=8.0.19 supports aliases in the VALUES and SET clauses
of INSERT INTO ... ON DUPLICATE KEY UPDATE statement for the row to be
inserted and its columns. It also generates warning from >=8.0.20 if
an old style used.
This enhancement detects the MySQL version and on the base of it uses
alias during the upsert call.
Also a user can override the version through the MySQL database
configuration. It helps to save/avoid one database query
(select version()) during the upsert method call or during connecting
to the MySQL database (version is needed if strict mode is enabled).
- added unit and functional tests
- updated number of unit tests to 1402
- updated upsert docs
- added ConfigUtils to avoid duplicates
Others:
- added the version database configuration everywhere
- docs added few lines about MySQL version configuration option
- docs updated database configurations, added a new missing options
Move all pivot related methods for the BelongsToMany relation into
the new InteractsWithPivotTable concern.
- rvalue overloads for BelongsToMany::as/withPivot
- added reserve where possible
- whitespaces and formatting
- also complete revisit
Added chunk, each, chunkMap, chunkById, eachById, sole, tap
in TinyBuilder::Concerns::BuildsQueries and TinyBuilder::soleValue().
- added tests
- added proxies to Model and Relation
- also added missing proxy for forPageAfterId()
It calls the given callback with the given value then return the value.
Also used it on few places as a proof that it works, the old code
looks cleaner though because it's flat.
- added a new config. option dont_drop, allows to define table that
will be excluded during dropAllTables(), has a default value
spatial_ref_sys for PostGIS
- implemented fluent commands, used only by the PostgreSQL Comment
command
- added tests for PostgreSQL schema builder
- reworked tst_Migrate to be able to run on all supported connections,
currently PostgreSQL and MySQL
- updated docs
Unrelated:
- added a new reference class IndexDefinitionReference for a nice API
during index definition, contains algorithm and language
- unified selectFromWriteConnection() in schema builders
Extracting these guard related methods to own class allows to call
GuardedModel::unguarded() regardless of a template parameters needed
on the Model class, before was needed to call
Model<Torrent, Relations..>::unguarded().
- also made the g_unguarded atomic
- bugfix reguard() try-catch-finally in GuardedModel::unguarded()
Added practically everything I wanted to have in except for updating
columns.
Needed to name the schema namespace as Orm::SchemaNs to avoid collision
with the Orm::Schema class.
- unit tests with great coverage
- new schema constants
- a new prefix_indexes and engine DB conncetion configurations
Others:
- IsModel tag
- enhanced columnize in the BaseGrammar
- used a new columnize logic in all grammars
- new constants
- new container utils class for joining containers
- new DB::driver() getter for QSqlDriver
- avoid possible crash in tests with pretend, added empty log checks
- clang tidy, excluded to word from short variable names
Transactions extracted to the Concerns::ManagesTransactions base class.
- bugfix includes
- logConnected()/logDisconnected() code wrapped in TINYORM_MYSQL_PING
- hitTransactionalCounters() extracted to Concerns::CountsQueries
- convertNamedToPositionalBindings() extracted to Concerns::LogsQueries
Queries counters extracted to the Concerns::CountsQueries base class.
- removed ConnectionInterface 😕😎🙌
- all methods are returning DatabaseConnection & instead of
ConnectionInterface
- includes cleanup after extraction
While ORM can be disabled, Orm::Utils has been split into Orm::Utils
and Orm::Tiny::Utils (Orm::Tiny::TinyUtils alias).
So when ORM is disabled then utils used only in the ORM will be
excluded from a final build.
- bugfix cmake undefined ORM option in TinySources
Added TINYORM_DISABLE_ORM macro controlled by ORM for CMake and
disable_orm for qmake. When TINYORM_DISABLE_ORM macro is defined then
only the query builder without ORM is compiled.
Also excludes ORM-related unit tests.