-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Expose enumType to DBAL to make native DB Enum possible #9382
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
|
I would not want a PHP enum to always be mapped to a MySQL enum. If we merge this, it must be an opt-in feature, please. |
|
The proposed change doesn't force using MySQL enum for all PHP enums, it just forwards metadata from ORM to DBAL to make it possible to implement in your application. Without the code in the first comment (which should be implemented in the application, not in the library) nothing will be changed. To make it clear, in no way I suggest using MySQL enums by default, it's just possibility for the application to implement this behavior if app want it, because right now it isn't possible, because there is no enough information on DBAL side. |
|
IMO we shouldn't make it easy to use |
|
We have been using MySQL At the same time, PHP native Enum has identical native representation in MySQL - with the same advantages and disadvantages, so why we are okay with PHP Enum and want make harder it reflection to MySQL Enum? Again, I don't suggest using MySQL Enum by default for everyone, I just propose to forward information about enumType from ORM to DBAL layer to give application developers the right to make a decision whether they want to use MySQL Enum or not. Default behavior is not changed in any way. And this small patch will help to avoid forking/patching Thank you for your understanding. |
|
It is worth mentioning that we still have a chapter in the official Doctrine ORM documentation about
And we were given a solution to make it possible with ORM: https://www.doctrine-project.org/projects/doctrine-orm/en/2.11/cookbook/mysql-enums.html#solution-2-defining-a-type So the proposed solution is already used by many developers in many projects. And it seems logical to replace old-fashioned approach with |
|
I have myself used enums in the past year, and I must say I have been burnt, because of how key the "never-changing values without any additional data" part is. I had this table with millions of rows that I needed to migrate to allow one more value, and it was very painful. So you see, it's not religion or superstition, it's based on experience.
This is a great analogy. And I was saying that knives shouldn't be easily accessible to anybody. But since you still have a define a DBAL type, maybe this is acceptable.
If you're that worried about memory, you can have a lookup table with an id column and a column to hold the value for the enum, and pick an appropriate type for the id column, see https://stackoverflow.com/questions/761211/how-to-handle-enumerations-without-enum-fields-in-a-database/761343#761343
Maybe we should alter this cookbook… in the example, a status is used, which is definitely not something with a fixed set of values that will never evolve. Also, the fact that there is a cookbook entry for this shows that we have no intention of supporting
I'm not favorable to this PR, but maybe it's just me, let's see if other maintainers think this is fine. Regardless of the benefits and drawbacks of |
Online altering of ENUM values (without table rebuilding) is supported since MySQL 8.0.12 (2018-07-27), see Online DDL Operations:
So it is a fast operation since 2018, at least when you add a new value to the end (the most often use case in my experience).
It might be the case for a very tiny application, but no more. One of our application has 84 EnumTypes, so instead of creating 84 tiny classes with enumerated values we should:
Well, it seems too much work for such an easy task, isn't it? Remember we need to create business value also, not only write code for the code itself. And there is already existing solution out-of-the-box, why not to use it if you know where and how to use it? Again, I'm not evangelist of ENUM and don't suggest using it for everybody and everywhere, but let's not reject the things which do their job efficiently. It's like a supercars, they don't fit to everybody, but they greatly do their job for people who can control them.
It's not true since PHP Enums, because now the value is validated far before persisting it to the DB, because Enum won't be instantiated at all. That is one of the reasons why I prefer PHP Enums over EnumTypes.
Yes, it also confuses me, but it just informs DBAL that a column holds Enum, this information might be necessary in the future for full-fledged support of PHP Enums, for example, for handling Enum default values or something else. |
beberlei
left a comment
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 simple and good enough change to do. All other things set in a @Column are exposed to Schema as well, so this should too.
| // the 'default' option can be overwritten here | ||
| $options = $this->gatherColumnOptions($mapping) + $options; | ||
|
|
||
| if (isset($mapping['enumType'])) { |
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 feel this code should be moved into gatherColumnOptions, because that is where it should come from.
|
The pros and cons of using an ENUM type are irrelevant to this change imho, its a choice everyone can make, and this just exposes the value to Schema component, similar to all other data that is available when set in ORM mappings. |
greg0ire
left a comment
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.
Should the cookbook you mentioned be changed in any way? As I said, I find it weird to forward something to the DBAL if it does not natively do something with it, but if at least the possible use of this option is mentioned somewhere, that's already better.
|
I'm fine with the change after reading the discussion. But:
|
|
SchemaToolTest already does a lot in this area, it can probably be extended for this. Docs can be done seperately, they haven't existed before either. |
b03983d to
9ccf93a
Compare
|
@beberlei Thank you! I've moved the code to Should we target this change to |
|
@javer Why not, this is somewhat an omission of the enum feature PR and can be considered a bug for adding this without integrating in all the proper places. Its also tiny enough to be a low risk for breakage if we consider this a new feature instead. |
9ccf93a to
d02d9c7
Compare
|
@beberlei Done, I've rebased on |
d02d9c7 to
b5c94c3
Compare
|
Thank you, @javer! |
* Expose enumType to DBAL to make native DB Enum possible (#9382) * Accessing private properties and methods from the same class is forbidden (#9311) Resolves issue doctrine/common#934 Update docs/en/cookbook/accessing-private-properties-of-the-same-class-from-different-instance.rst Co-authored-by: Claudio Zizza <[email protected]> Update docs/en/cookbook/accessing-private-properties-of-the-same-class-from-different-instance.rst Co-authored-by: Claudio Zizza <[email protected]> Fix review issues * Update baselines for DBAL 3.3 (#9393) Co-authored-by: Vadim Borodavko <[email protected]> Co-authored-by: olsavmic <[email protected]>
* 2.12.x: Deprecate MultiGetRegion (doctrine#9397) Fix type on loadCacheEntry (doctrine#9398) Update baselines for DBAL 3.3 (doctrine#9393) Accessing private properties and methods from the same class is forbidden (doctrine#9311) Expose enumType to DBAL to make native DB Enum possible (doctrine#9382)
The idea behing this is the following: by overriding DBAL built-in StringType we can use native enums directly in the database. But to make it possible we need enumType information on DBAL side, right now it's holded only in ORM mapping and isn't passed to DBAL in SchemaTool.
By doing this the following entity
results in the migration: