Summary | Rdo: Make *- to-one-relations aware of "no relation" state |
Queue | Horde Framework Packages |
Queue Version | Git master |
Type | Enhancement |
State | Assigned |
Priority | 1. Low |
Owners | ralf.lang (at) ralf-lang (dot) de |
Requester | ralf.lang (at) ralf-lang (dot) de |
Created | 12/22/2011 (4892 days ago) |
Due | |
Updated | 01/02/2017 (3054 days ago) |
Assigned | 01/28/2016 (3394 days ago) |
Resolved | |
Milestone | |
Patch | No |
patch, at least I did not find an elegant way. to say "join result AND
everything where the join key is null.
The alternative is also not great:
Always use the lazy code path (but on load instead of on request)
For broken relation keys, my current approach is to overload certain
mappers to null the key on failure or on ::delete of the partner. It's
sort of messy and should best be handled in the relation configuration:
'hosts' => array('type' => Horde_Rdo::ONE_TO_MANY,
'foreignKey' => 'device_id',
'onDelete' => ['delete' | 'removeRelation']
'mapper' => 'APP_HostMapper'),
different part of code than eager relations.
lazy relations:
Base.php __get triggers a findOne on the target mapper with either a
supplied query object (undocumented?) or the defined foreignKey
field's value. A findOne without restrictions catches the first
object, if any exist or null otherwise. I think I have fixed THIS
eager relations:
REFERENCING Objects with broken eager relations of either type (null
value or wrong key value) simply aren't created. No exception is
thrown until code wants to access the object's properties.
This seems to be handled by Horde_Rdo_Query generating an INNER JOIN
which results in no object
No idea how to tackle this.
Fix lazy to-one relations as in ticket #10880 Add tests for base
objects not loaded when eager to-one relations don't work Change tests
to reflect lazy relations now work as expected for failing cases
11 files changed, 97 insertions(+), 44 deletions(-)
http://git.horde.org/horde-git/-/commit/b0cfa915b40a5f61321b446bd18bebbe07f6fd94
Add some unit tests to Horde_Rdo
testToOneRelationReturnsNullWhenKeyIsNotFound show to-one-relation
returns null if referenced object id doesn't exist (shouldn't this
throw exception?) testToOneRelationReturnsNullWhenKeyIsNull shows
actually Rdo fetches the first entry of the relation type when a to
one relation's key field is '' or null (should return null or throw
exception)
see ticket #10880 [10880]
11 files changed, 263 insertions(+), 0 deletions(-)
http://git.horde.org/horde-git/-/commit/dd36e1abd2961826262ff3c3ee551347db057d5c
State ⇒ Feedback
by design, but returning arbitrary records on a null reference key
definitly is not.
Throwing an exception could be considered a bug fix instead of a BC
break, but returning an empty result sounds feasible too. If we are
going to throw an exception, than rather in the case where the linked
record is missing, than when the link is NULL.
It would speed up implementing a solution if you could create unit
tests for those two cases.
I'd suggest to either return no object or an exception.
Consistence with to-many-relations is hard.
These relations always return a list object, possibly an empty one.
As to-one-relations are often used in chains (at least in my code)
I'd prefer a clean exception over an empty result but the current
situation is worst for me.
'' or NULL), but the referenced object is no longer there, I get an
empty result rather than a wrong object or an exception. Trying to
blindly execute code on this not-an-object results in a crash.
Changing this too would be clearly BC breaking.
Priority ⇒ 1. Low
Type ⇒ Enhancement
Summary ⇒ Rdo: Make *- to-one-relations aware of "no relation" state
Queue ⇒ Horde Framework Packages
Milestone ⇒
Patch ⇒ No
State ⇒ New
for the corner case of NULL or "empty string" in the relation key
field is misleading.
Example:
Two data entities exist, a network host table and a certificate table.
A host may or may not have a certificate.
Since certificates are managed for other objects too it is not
feasible to reverse the relation and say the certificate must
reference the host.
CREATE TABLE `appname_hosts` (
`host_id` int(10) NOT NULL auto_increment,
`certificate_id` int(10) default NULL,
#[... more fields that don't matter here]
PRIMARY KEY (`host_id`)
) ENGINE=MyISAM AUTO_INCREMENT=125 DEFAULT CHARSET=latin1
CREATE TABLE `appname_certificates` (
`certificate_id` int(10) unsigned NOT NULL auto_increment,
`certificate_crt` text,
`certificate_key` text,
`ca_id` int(10) default NULL,
`certificate_cn` varchar(100) default NULL,
`certificate_csr` text,
`certificate_pkcs12` text,
PRIMARY KEY (`certificate_id`)
) ENGINE=MyISAM AUTO_INCREMENT=151 DEFAULT CHARSET=latin;
Now we have a Appname_HostMapper Class with relation
protected $_lazyRelationships = array(
'certificate' => array('type' => Horde_Rdo::ONE_TO_ONE,
'foreignKey' => 'certificate_id',
'mapper' => 'Appname_CertificateMapper')
);
Now when I have a Host table entry with value of '' or NULL, I do get
an instance of Appname_Certificate as a response, usually the first
entry in the table (with default order).
Rdo currently doesn't understand the concept of a missing relation.
I'd suggest to either return no object or an exception.
Consistence with to-many-relations is hard.
These relations always return a list object, possibly an empty one.
As to-one-relations are often used in chains (at least in my code) I'd
prefer a clean exception over an empty result but the current
situation is worst for me.
My current workaround is to check length($this->certificate_id) before
accessing $this->certificate but it's obviously not a clean solution.
I've classified this as an enhancement rather than a bug because it
breaks current behaviour and Rdo possibly wasn't designed with this
case in mind.