Added polymorphic many-to-many relationships.#1319
Added polymorphic many-to-many relationships.#1319wleona3 wants to merge 1 commit intopropelorm:masterfrom
Conversation
|
Wow, that's a rather big change, thanks dude! I'd rather want to see that beauty in https://github.com/propelorm/Propel3 :P |
|
Thanks for the kind words marcj, unfortunately our company will be stuck with PHP 5.6 for the foreseeable future so we'll be sticking with Propel2 |
|
Whitespace corrected! |
There was a problem hiding this comment.
This branch passes CI when rebased on latest master. The new tests also pass when rebased.
Because it's been open for a while we should give this a proper read-over to check how the feature works and see if there's any code changes needed to meet the new standards on the project.
It looks like a really cool feature to add to Propel.
| /** | ||
| * | ||
| * add | remove | set | get | ||
| * +--------------------------------------------------- | ||
| * add | 1 2 3 4 | ||
| * remove | 5 6 7 8 | ||
| * set | 9 10 11 12 | ||
| * | ||
| */ | ||
|
|
||
|
|
||
|
|
||
| /* | ||
| * #################################### | ||
| * 1. add, add | ||
| */ |
There was a problem hiding this comment.
| /** | |
| * | |
| * add | remove | set | get | |
| * +--------------------------------------------------- | |
| * add | 1 2 3 4 | |
| * remove | 5 6 7 8 | |
| * set | 9 10 11 12 | |
| * | |
| */ | |
| /* | |
| * #################################### | |
| * 1. add, add | |
| */ | |
| /** | |
| * | | Add | Remove | Set | Get | | |
| * |--------|-----|--------|-----|-----| | |
| * | Add | 1 | 2 | 3 | 4 | | |
| * | Remove | 5 | 6 | 7 | 8 | | |
| * | Set | 9 | 10 | 11 | 12 | | |
| * | |
| * Test the intersection of `Add` and `Add`. | |
| */ |
There was a problem hiding this comment.
I'm not 100% sure if these comments are meaningful or should be removed, I just wanted to improve the presentation of it.
Incognito
left a comment
There was a problem hiding this comment.
This is a really cool feature and I think it will be useful to anyone with polymorphic needs.
| * #################################### | ||
| * 1. add, add | ||
| */ | ||
| public function test1() |
There was a problem hiding this comment.
| public function test1() | |
| public function testCombinations() |
I suspect this test should be broke into three tests, based on the cyclical appearance of setup + assert code in here.
| class GeneratedObjectM2MRelationPolymorphic extends PlatformDatabaseBuildTimeBase | ||
| { | ||
| /** | ||
| * Tests for a M2M relation with three pks where each is a FK. |
There was a problem hiding this comment.
| * Tests for a M2M relation with three pks where each is a FK. | |
| * Tests for a Many-to-Many relation with three PKs where each has its own FK. |
| /** | ||
| * | ||
| * add | remove | set | get | ||
| * +--------------------------------------------------- | ||
| * add | 1 2 3 4 | ||
| * remove | 5 6 7 8 | ||
| * set | 9 10 11 12 | ||
| * | ||
| */ | ||
|
|
||
|
|
||
|
|
||
| /* | ||
| * #################################### | ||
| * 1. add, add | ||
| */ |
There was a problem hiding this comment.
I'm not 100% sure if these comments are meaningful or should be removed, I just wanted to improve the presentation of it.
| @@ -0,0 +1,43 @@ | |||
| <?php namespace Propel\Common\Util; | |||
|
|
|||
| class CartesianProduct | |||
There was a problem hiding this comment.
I would like to see some way to limit the size of this. Cartesian products end up being expensive for both CPU and RAM in easily process-crashing-ways.
|
|
||
| class CartesianProduct | ||
| { | ||
| public static function get($input) { |
There was a problem hiding this comment.
There's a good opportunity to decrease the logical nesting here. If I get a moment I might propose an alternative that uses generators (since propel is now 7.1+).
| $script .= " | ||
| if ($value) { | ||
| $script .= " | ||
| \$entryPk[$idx] = '$value';"; | ||
| } else { | ||
| $script .= " | ||
| \$entryPk[$idx] = \$combination[$combinationIdx]->get{$foreign->getPhpName()}();"; | ||
| } |
There was a problem hiding this comment.
Because addCrossFkScheduledForDeletion is already quite complex we should do our best to keep reducing it whenever possible. I see an opportunity here to simply put this additional logic into a protected method.
It could also help reduce duplication, as the other two code hunks in this patch look very similar to me.
| return 0 !== count($cols); | ||
| } | ||
|
|
||
| public function isTheSamePolymorphicSignature(ForeignKey $fk) |
There was a problem hiding this comment.
There should be a discussion around the names introduced in this model as they're going to become highly visible.
| $sortedCols = $this->getLocalColumns(); | ||
| sort($sortedCols); | ||
|
|
||
| return sha1(implode('|||', $sortedCols)); |
There was a problem hiding this comment.
I don't know about everyone else, but any time I've wanted to generate something like a "unique signature" it's always come back to haunt me in 2 ways:
- It ends up being slow when called hundreds of times in a loop.
- It ends up being really hard to change in a BC way because it isn't abstracted out of the class itself.
It might be a good feature but we should look at improving these two points. Perhaps the signature generation could be even simpler than it is, and/or it could also be moved out of the class.
| if ($fk->isAtLeastOneLocalPrimaryKeyIsRequired() && | ||
| $crossFK->isAtLeastOneLocalPrimaryKeyNotCovered($fk)) { | ||
| $crossFK->addCrossForeignKey($fk); | ||
| // group all polymorphic fks |
There was a problem hiding this comment.
Let's find a way to reduce the complexity of this class. It was already 2 nested foreach loops, both nested inside if statements, this has now increased a fair bit.
I'd also like to understand more about the performance impact of this change, and what cases users of Propel will need to be cautious about getting into.
|
Justification for Beta6.
|
Allows for polymorphic many-to-many relationships. Unfortunately at this time does not allow additional static FKs. The builder almost supports it, but since each polymorphic sibling requires a unique relation, the builder tries to also create a new relation for the other static FKs. Example: I have a table that has two static FK relationships A and B and two polymorphic siblings, C1 and C2. When creating object A the builder has to create properties and methods for the unique C1 and C2 relationships, but then also creates two B relationships, creating duplicate properties and methods. Not sure exactly how to implement that properly. But if that caveat is fixed, this would support any combination of static FKs and Polymorphic FKs.