Conversation
bdcf355 to
177dcc4
Compare
|
@BastianLedererIcinga Please note that this must not break anything in other products. Icinga DB Web for example must still work without Icinga/icingadb-web#1398, albeit with a deprecation notice here and there. |
This is required to establish type symmetry as the base's methods also accept `NULL` to be able to direcly pass a getters return value to the appropriate setter.
There is now `Relation::bindTo(Model, string, Resolver)` in order to pass control to relations how they're prepared. Since the introduction of `BelongsToMany`, it is established that a relation may resolve to multiple hops and thus needs to perform steps n-times rather than a single time. It's this reason because registering the alias and resolving the filter is now a responsibility of a relation rather than the resolver. Relations know it better how to and the override of `bindTo` in `BelongsToMany` proves it as it turned out that it is necessary to allow referencing the junction table in either the filter or the through filter in order to be able to better reverse relations. Qualification must be done by a relation in turn as well, as otherwise there's a mis-match with what's allowed to reference and what can be qualified. My initial attempt was to teach `Relation::resolve()` this, but without passing it the resolver and changing the return value this doesn't make sense. Sadly, this is out of the question as this is a breaking change. Say hello to `Relation::setFilterSubjects()` due to this.
BastianLedererIcinga
left a comment
There was a problem hiding this comment.
The only real issue I found is that referencing the source table in setThroughFilter() throws an exception when reversing the relation.
I tested this by modifying the RestrictedUser <-> Car relation with this ->setThroughFilter(Filter::equal('restricted_user.id', 5)), it throws:
InvalidArgumentException: Invalid relation alias "restricted_user". Available options are: car => ipl\Tests\Orm\Car, car_user => ipl\Tests\Orm\CarUser.
This works fine on main and the setThroughFilter() docblock explicitly states that referecing the source's columns is supported.
177dcc4 to
bcd7fd8
Compare
|
Stopping for now. Cannot wrap my head around the reason for the last remaining failing test. Review comments resolved, though. |
ab3da64 to
3082909
Compare
d3a89ab to
c10c699
Compare
c10c699 to
cc5ee0c
Compare
BastianLedererIcinga
left a comment
There was a problem hiding this comment.
I can't test the added fix works on postgres, the idea looks good and nothing seems to break on Mysql, so LGTM if the deprecation warning is fixed in your Postgres env.
|
Sorry 🤣 I just changed the other deprecation notice to include more solutions. |
Changes the way relations can be reversed drastically as it is now possible to influence the relation to use during reversal with `::setReverseName(string)` which allows Icinga DB Web to drop the error-prone `to.from` and `from.to` relations. An additional change is that it is now not mandatory anymore to define relations that are solely being required because of sub-queries. Missing relations on the reversed path are automatically registered. For this, each relation type now has its specific counterpart which is possible to override with `::setReverseClass(class-string)`. The default however, is to use the same type which is the case for `BelongsToOne` and `BelongsToMany`. For `BelongsTo` a sane override has been chosen that is based on how it's used at the moment in our products, as `HasOne` and `HasMany` may both be appropriate. But the latter clearly is used more often.
Since `::reverse()` uses the source's table alias by default as reverse name, a deprecation notice is triggered if the original forward path uses a different name, indicating that it is necessary to use this name as explicit reverse name. As `Query::createSubQuery()` now overrides the source's relations, `Query::derive()` cannot use it anymore as otherwise the result will not have the relations it had previously. This must be done in order to avoid breaking current usages that rely on specific relations for filters or columns. A side-effect of this is, that the resulting query does not use the `sub_` alias prefix anymore. fixes #170
The new implementation of `::derive()` does not join the source table in the resulting query anymore and has no fallback like `::createSubQuery()` still has. The result is that an invalid filter is created with a `NULL` value. To avoid this, I opted to return a so-called `NoopQuery` instead of re-implementing the same fallback which issues a SQL query for no reason.
7b2c3ab to
3cc4ef0
Compare
|
The latest commit should resolve the error in db-web's dependency children/parents search bar suggestions. |
Changes the way relations can be reversed drastically as it is now possible to influence the relation to use during reversal with
::setReverseName(string)which allows Icinga DB Web to drop the error-proneto.fromandfrom.torelations.An additional change is that it is now not mandatory anymore to define relations that are solely being required because of sub-queries. Missing relations on the reversed path are automatically registered. For this, each relation type now has its specific counterpart which is possible to override with
::setReverseClass(class-string). The default however, is to use the same type which is the case forBelongsToOneandBelongsToMany. ForBelongsToa sane override has been chosen that is based on how it's used at the moment in our products, asHasOneandHasManymay both be appropriate. But the latter clearly is used more often.Since
::reverse()uses the source's table alias by default as reverse name, a deprecation notice is triggered if the original forward path uses a different name, indicating that it is necessary to use this name as explicit reverse name.fixes #170
--
A substantial preparation for this is the introduction of
Relation::bindTo(Model, string, Resolver)in order to pass control to relations how they're prepared. Since the introduction ofBelongsToMany, it is established that a relation may resolve to multiple hops and thus needs to perform steps n-times rather than a single time. It's this reason because registering the alias and resolving the filter is now a responsibility of a relation rather than the resolver.Relations know it better how to and the override of
bindToinBelongsToManyproves it as it turned out that it is necessary to allow referencing the junction table in either the filter or the through filter in order to be able to better reverse relations.Qualification must be done by a relation in turn as well, as otherwise there's a mis-match with what's allowed to reference and what can be qualified. My initial attempt was to teach
Relation::resolve()this, but without passing it the resolver and changing the return value this doesn't make sense. Sadly, this is out of the question as this is a breaking change. Say hello toRelation::setFilterSubjects()due to this.