Commit | Line | Data |
7efc9842 |
1 | How to allow custom relations: |
2 | |
3 | * add_relationship is augmented to accept a coderef in addition to the |
4 | traditional { foreign... => self... } hashref to specify an ON join |
5 | condition. The coderef's signature is: |
6 | |
7 | my ( $me_alias, $rel_alias, $me_result_source, $rel_name, $optional_me_object ) = @_; |
8 | |
9 | Normally a condition can be constructed using only the first 2 arguments |
10 | (i.e. { "$left_alias.colA" => { '>', \"$right_alias.colB" } } ). |
11 | |
12 | The next two arguments are supplied in case the coderef wants to do something |
13 | clever. Having the result source and the corresponding rel-name (name, not |
14 | alias) - one has access to virtually the entire DBIC object structure, |
15 | including a raw $dbh (but don't do that) |
16 | |
17 | The last argument is supplied in cases like $row_obj->custom_relationship |
18 | and *may* be used as an optimization path, see discussion of return values |
19 | below. |
20 | |
21 | |
22 | The 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 |
6c4f4d69 |
39 | hashref. Naturally the values of this hashref *must be* plain |
40 | scalars. |
7efc9842 |
41 | (Note - such rel-to-ident resolution is currently possible for *all* |
42 | DBIC relationships, but can not be guaranteed for all custom rels |
43 | possible via this syntax. Thus the escape hatch of a *mandatory* |
44 | ON clause, which can be used to construct a full-blown JOIN even in |
45 | the $obj->rel case |
46 | |
47 | |
48 | Why the complexity of two RVs - custom rels are generally simplifiable |
49 | right? |
50 | |
51 | This is generally true, except when it isn't. The main issue is that a |
6c4f4d69 |
52 | coderef is a blackbox, and we want to keep it this way for simplicity. |
53 | This means that no state is communicated from DBIC to the coderef (except |
7efc9842 |
54 | for the optional row-obj), and no state is communicated out when the |
55 | coderef returns (i.e. you can use this hashref for real joins but not for |
56 | set_from_related). |
57 | |
58 | Here are a couple of edge cases when it is crucial to know if we have |
59 | a return value for a specific scenario |
60 | |
61 | - Given a relationship |
62 | { 'artist.name' => { '!=', 'bob' }, 'artist.id' => \'cds.artistid' } |
63 | we *have* to do a full join when doing $artist->cds, as this is the |
64 | only way to evaluate the artist.name condition. For this we need a |
65 | defined $on_as_where, but a missing $vals_from_related, which will |
6c4f4d69 |
66 | signal the need to wrap a full query. Also set_from_related will |
67 | throw an exception here, as it largely makes no sense. |
7efc9842 |
68 | |
6c4f4d69 |
69 | - Given a relationship |
70 | { 'cd.year' => '2000', 'artist.id' => \'cds.artistid } |
71 | we could use the knowledge of the year to pre-fill the correct value |
72 | via $artist->create_related('year_2k_cd', {}); |
7efc9842 |
73 | |
74 | |
75 | What needs to be adjusted (non-exhaustive summary): |
76 | |
77 | * $obj->create_related is implemented on top of search_related and |
78 | set_from_related. While search_related will always work, the other |
79 | may not as discussed above |
80 | |
81 | * Relationships definitions are treated as fully-introdspectable structures |
82 | and multiple codepaths expect _resolve_condition to always return something |
83 | akin to $vals_from_related above. A grep for _resolve_condition will |
84 | highlight the problematic use-cases |
edcecdbb |
85 | |
86 | Additional Note: |
87 | |
88 | When using extended_rels all cascade options default to 0. |