Skip to content

[DoctrineBridge] Ulid and Uuid as Doctrine Types #37678

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

Conversation

gennadigennadigennadi
Copy link
Contributor

Q A
Branch? master
Bug fix? no
New feature? yes
Deprecations? no
Tickets #36102
License MIT

This Types Implementations are basically copies from https://github.com/ramsey/uuid-doctrine, with minor tweaks to use Symfonys Uid classes.

I am not done yet. I'm going to implement some UnitTests and I also do need to add the Changelog Entries.

And I do ask my self if the Types should be registered automatically (with the recipe?), cause it would collide with Ramseys uuids implementation.

@stof
Copy link
Member

stof commented Jul 27, 2020

Rather than adding a required dependency on symfony/uid in symfony/doctrine-bridge (which would then bring this package to everyone using the Doctrine Bridge for another reason), I think we should create a dedicated bridge package between doctrine/dbal and symfony/uid (and then, it becomes possible to have a smart default registering the type based on the fact that the package is installed, as there would be no reason to install that bridge without configuring it).

My own opinion (note that this has not been discussed yet with the other members of the core team to take a decision) is that we should not use symfony/doctrine-bridge to host more integrations. Making a bridge between all Symfony components and all Doctrine packages at once makes it harder to handle dependencies and makes it impossible to have smart defaults.

@nicolas-grekas nicolas-grekas added this to the next milestone Jul 29, 2020
@nicolas-grekas
Copy link
Member

Thanks for the PR. I didn't think about @stof's proposal but that shouldn't prevent moving forward on the rest. Can you please remove the declare statements (we don't use strict mode) and apply the fabbot patch?

@gennadigennadigennadi gennadigennadigennadi force-pushed the feature/add-uid-as-doctrine-types branch from d3af2ba to d0b62b4 Compare July 29, 2020 15:06
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some random thought for the discussion:

  • don't miss adding a changelog entry
  • what about adding implementations of AbstractIdGenerator?
  • do we want storage-optimized types? ie UuidAsBinaryType, UlidAsBinaryType and UlidAsUuidType?

@@ -22,6 +22,7 @@
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.15",
"symfony/uid": "^5.1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be added to require-dev
the constructors of the above classes could then do a runtime check + throw if the component is missing (see similar LogicException in the codebase when a dep is missing)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Base Type class has a private construct https://github.com/doctrine/dbal/blob/e7c4149a13f1267380a8061452816a1a33909dc1/lib/Doctrine/DBAL/Types/Type.php#L134, therefor I can not do the runtime check you are suggesting.

I'm going to implement IdGenerators tomorrow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, if we go for my proposal of a separate package, the issue of the optional dependency is solved, btw.

@gennadigennadigennadi gennadigennadigennadi force-pushed the feature/add-uid-as-doctrine-types branch 2 times, most recently from a77cbed to 0e9424c Compare July 29, 2020 16:49
use Doctrine\ORM\Id\AbstractIdGenerator;
use Symfony\Component\Uid\UuidV4;

final class UuidGenerator extends AbstractIdGenerator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we have UuidV4Generator but also UuidV1Generator and UuidV6Generator? (no V3 nor V5)

@nicolas-grekas nicolas-grekas changed the title Add: Ulid and Uuid as Doctrine Types [DoctrineBridge] Ulid and Uuid as Doctrine Types Aug 1, 2020
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Base Type class has a private construct

OK, then we can add the check just before the class declaration

5.2.0
-----

* added support for symfony/uid as types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest mentioning what this PR provides by giving the name of the new classes

/**
* @throws ConversionException
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't this deserve an AbstractBinaryUidType?

@nicolas-grekas
Copy link
Member

I think we should create a dedicated bridge package between doctrine/dbal and symfony/uid (and then, it becomes possible to have a smart default registering the type based on the fact that the package is installed, as there would be no reason to install that bridge without configuring it).

Why can't we have a smart default without a dedicated bridge? Can't DoctrineBundle register the types when detecting that Uid is installed?

@stof
Copy link
Member

stof commented Aug 3, 2020

hmm, for this particular case, we could indeed define a smart default based on 2 packages. But this does not remove the more complex management of dependencies (as we have to manage them through conflict rules rather than requirements).
And I think registering custom types adds some code running during the booting phase and/or the first instantiation of the connection service. So registering unused types might no be a good idea. Just having the uid component installed does not mean you want to use the new DBAL types for them. If they were in a dedicated package, that would be a much stronger signal (why installing a package providing the uid-based DBAL types if you don't want to register them ?)

@ogizanagi
Copy link
Contributor

This does not solve any of @stof 's concerns, but we already have components with their own bridges to Doctrine shipped within it.
But if we mean to ask the user to require another dep for such a simple need, I'd rather go with @stof 's suggestion which indeed conveys more than the doctrine bridge itself.

One solution for now may be to ship this bridge into the component itself and split it later into a dedicated package if we want it to happen, as we did for Messenger transports?

@gennadigennadigennadi
Copy link
Contributor Author

gennadigennadigennadi commented Aug 15, 2020

Todo:

  • Register Types if Uid Component is installed
  • Update Changelog

@gennadigennadigennadi gennadigennadigennadi force-pushed the feature/add-uid-as-doctrine-types branch from 77d8adf to ffc49ae Compare August 16, 2020 17:45
@gennadigennadigennadi
Copy link
Contributor Author

I have added a CompilerPass to register the Types if no uuid or ulid is already registered. An alternative is to register them directly inside of the DoctrineExtension .

@fabpot
Copy link
Member

fabpot commented Aug 22, 2020

@gennadigennadigennadi Can you finish the items on your todolist and move the PR to a non-draft status?

@gennadigennadigennadi gennadigennadigennadi marked this pull request as ready for review August 23, 2020 15:42
Copy link
Member

@fabpot fabpot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stof Can you review this one?

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you think about the DoctrineBundle's side?
What about opening a PR on it to integrate this work?

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the double review, here is one more note.
Could you please add some tests maybe also?

@gennadigennadigennadi
Copy link
Contributor Author

Did you think about the DoctrineBundle's side?
What about opening a PR on it to integrate this work?

That's exactly what I was about to do as soon this PR gets accepted, but I can open a PR sooner if you like.

@@ -64,6 +65,7 @@
},
"suggest": {
"symfony/form": "",
"symfony/uid": "",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed

@nicolas-grekas nicolas-grekas force-pushed the feature/add-uid-as-doctrine-types branch from ca46e63 to f44fa34 Compare September 3, 2020 19:52
@nicolas-grekas
Copy link
Member

Thank you @gennadigennadigennadi.

* file that was distributed with this source code.
*/

namespace Symfony\Bridge\Doctrine\Types;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The namespace does not match the folder path. BTW, why not call it "Generator"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you send a PR please to fix the namespace?
and change the namespace to Uid meanwhile

why not call it "Generator"?

not sure what you mean here sorry...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not call it "Generator"?

got it!
yes, let's name it Generator
I'm looking forward to your PR :)
If you can add tests, that'd be awesome.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IdGenerator actually.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, it was just not very clear to have the namespace "Id" but "Uid" looks better to me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The namespace does not match the folder path. BTW, why not call it "Generator"?

Good catch.
I just haven't spent enough time with implementing those Generators.

Thx.

fabpot added a commit that referenced this pull request Oct 6, 2020
This PR was merged into the 5.2-dev branch.

Discussion
----------

[DoctrineBridge] fix and replace namespace to Uid

| Q             | A
| ------------- | ---
| Branch?       | master <!-- see below -->
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | #37678 (comment) <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT
| Doc PR        | ... <!-- required for new features -->

This post should also be corrected: https://symfony.com/blog/new-in-symfony-5-2-doctrine-types-for-uuid-and-ulid cc @javiereguiluz

Commits
-------

28d1169 [DoctrineBridge] fix and replace namespace to Uid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants