-
Notifications
You must be signed in to change notification settings - Fork 401
Added polymorphic many-to-many relationships. #1319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /** | |
| * | |
| * 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% sure if these comments are meaningful or should be removed, I just wanted to improve the presentation of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.