cascades default to 0 when using extended rels
[dbsrgits/DBIx-Class.git] / BRANCH
CommitLineData
7efc9842 1How to allow custom relations:
2
3* add_relationship is augmented to accept a coderef in addition to the
4traditional { foreign... => self... } hashref to specify an ON join
5condition. The coderef's signature is:
6
7my ( $me_alias, $rel_alias, $me_result_source, $rel_name, $optional_me_object ) = @_;
8
9Normally a condition can be constructed using only the first 2 arguments
10(i.e. { "$left_alias.colA" => { '>', \"$right_alias.colB" } } ).
11
12The next two arguments are supplied in case the coderef wants to do something
13clever. Having the result source and the corresponding rel-name (name, not
14alias) - one has access to virtually the entire DBIC object structure,
15including a raw $dbh (but don't do that)
16
17The last argument is supplied in cases like $row_obj->custom_relationship
18and *may* be used as an optimization path, see discussion of return values
19below.
20
21
22The coderef is expected to return one or two values
23 ($on_as_where, $vals_from_related):
24
25- an *SQLA* where-clause compatible structure (this implies that
26 t1.cola = t2.colb must be written as { t1.cola => \'t2.colb' }).
27 There are plans to introduce an -ident => 'string' SQLAHacks
28 operator to make the \'column' unnecessary (and allow proper
29 quoting when needed). The DBIC-SQLA shim is then augmented to
30 recognize such conditions, and pass them through _recurse_where
31 in order to produce the final textual ON clause (folding whatever
32 bind values at the proper places)
33
34- an OPTIONAL hashref of resolved values, when an $optional_me_object
35 is supplied to the coderef. This is the data that will be used to
36 make $some_row_obj->set_from_related ($another_obj) work, and also
37 to optimise $row_obj->relationship calls, by avoiding a full-join
38 and instead constructing a WHERE clause with the contents of said
39 hashref
40 (Note - such rel-to-ident resolution is currently possible for *all*
41 DBIC relationships, but can not be guaranteed for all custom rels
42 possible via this syntax. Thus the escape hatch of a *mandatory*
43 ON clause, which can be used to construct a full-blown JOIN even in
44 the $obj->rel case
45
46
47Why the complexity of two RVs - custom rels are generally simplifiable
48right?
49
50This is generally true, except when it isn't. The main issue is that a
51coderef is blackbox, and we want to keep it this way for simplicity.
52This means that no state is communicate from DBIC to the coderef (except
53for the optional row-obj), and no state is communicated out when the
54coderef returns (i.e. you can use this hashref for real joins but not for
55set_from_related).
56
57Here are a couple of edge cases when it is crucial to know if we have
58a return value for a specific scenario
59
60- Given a relationship
61 { 'artist.name' => { '!=', 'bob' }, 'artist.id' => \'cds.artistid' }
62 we *have* to do a full join when doing $artist->cds, as this is the
63 only way to evaluate the artist.name condition. For this we need a
64 defined $on_as_where, but a missing $vals_from_related, which will
65 signal the need to wrap a full query
66
67- Given the same relationship as above, we want
68 $new_cd->set_from_related($artist) to do the right thing depending
69 on the name of $artist - the coderef would be tasked to return
70 { artistid => xxx } or {} depending on the value of $artist->name
71
72
73What needs to be adjusted (non-exhaustive summary):
74
75* $obj->create_related is implemented on top of search_related and
76 set_from_related. While search_related will always work, the other
77 may not as discussed above
78
79* Relationships definitions are treated as fully-introdspectable structures
80 and multiple codepaths expect _resolve_condition to always return something
81 akin to $vals_from_related above. A grep for _resolve_condition will
82 highlight the problematic use-cases
edcecdbb 83
84Additional Note:
85
86When using extended_rels all cascade options default to 0.