-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
feat(AppFramework): Add full support for date / time / datetime columns #47329
Conversation
2346049
to
2d9b552
Compare
The next major (which we will have to update to soon) changed behaviour of DateTime: https://github.com/doctrine/dbal/blob/4.1.x/UPGRADE.md#bc-break-stricter-datetime-types |
@nickvergessen this is what I implemented already, whats breaking is that |
e62ee82
to
c059051
Compare
|
478135b
to
87fb634
Compare
3046e20
to
a236626
Compare
a236626
to
45e799b
Compare
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.
Nice
$this->addType('id', 'int'); | ||
$this->addType('tokenId', 'int'); | ||
$this->addType('clientId', 'int'); | ||
$this->addType('id', Types::INTEGER); | ||
$this->addType('tokenId', Types::INTEGER); | ||
$this->addType('clientId', Types::INTEGER); | ||
$this->addType('hashedCode', 'string'); | ||
$this->addType('encryptedToken', 'string'); | ||
$this->addType('codeCreatedAt', 'int'); | ||
$this->addType('tokenCount', 'int'); | ||
$this->addType('codeCreatedAt', Types::INTEGER); | ||
$this->addType('tokenCount', Types::INTEGER); |
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.
Someone should write a Rector rule for this
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.
Also this is not a clean replacement. Types::INTEGER
is 'integer'
not 'int'
which was used in almost all apps (at least the ones I maintain which now have dozens of Psalm errors 🙈
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.
Came back to check if this was intentional.
@susnux would there be any downside of allow "int" again?
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.
Came back to check if this was intentional.
Yes it was, as int
, double
, and bool
were never documented, only integer
, float
and boolean
were part of our documentation (since Nextcloud 20: https://docs.nextcloud.com/server/20/developer_manual/basics/storage/database.html#types ).
So the idea was to still allow them (it does not break) but make usage of it an error for static code checking to make developers aware they are using something undocumented.
Meaning to make it easier for us to change types if needed as we only need to change a single source of truth (the DB types).
would there be any downside of allow "int" again?
From my side: just duplicates a state, but lets add it back to make it less noisy for developers!
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.
Fair enough, int
indeed wasn't documented!
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.
addType('[^']+', 'int')
Results: 116
addType('[^']+', 'integer')
Results: 175
So while it was never documented, it was working and is used almost 40% of the time 🙈 So yeah we can not have it in docs going forward, but should keep an eye on keeping it working, so apps don't break unnecessarily.
For bool its more based with 17 (bool) to 68 (boolean), but still 20%
double I didn't find a single result (in apps we marketed, ship, support or maintain), neither for array or object.
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.
Ref #48837
This adds support for all Doctrine supported types, for the column types only the immutable variants needed to be added. But especially those types are the important ones, as our **Entity** class works by detecting changes through setters. Meaning if it is mutable, changes like `$entity->date->modfiy()` can not be detected, so the immutable types make more sense here. Similar the parameter types needed to be added. `Enity` and `QBMapper` needed to be adjusted so they support (auto map) those types, required when insert or update an entity. Also added more tests, especially to make sure the mapper really serializes the values correctly. Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de> Co-authored-by: Côme Chilliet <91878298+come-nc@users.noreply.github.com> Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
45e799b
to
0e54c2b
Compare
@@ -24,7 +25,7 @@ abstract class Entity { | |||
public $id; | |||
|
|||
private array $_updatedFields = []; | |||
/** @var array<string, AllowedTypes> */ | |||
/** @var array<string, \OCP\DB\Types::*> */ |
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 really not sure about this change.
- It indicates that 'bigint', 'smallint' and 'text' would be accepted, but
settype(
will break? - As mentioned on the other part it "dropped" the short forms
bool
andint
- Also
array
anddouble
are no longer?
In general I also don't like the mix of dictionaries. \OCP\DB\Types
was database field types. Now it's directly being used for PHP types as well. If this is intended, we need to map all, otherwise we need to use a different set of constants.
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.
First of all the AllowedTypes
was never released, in stable30 we just annotate as string
and the setter is just using settype
:
protected function setter(string $name, array $args): void { |
We already have 3 different mapping for db types: OCP\DB\Types
, IQueryBuilder
and the migration column types. With this we would have 4 different. But the underlying doctrine abstraction only knows 1.5 (query builder and table column types but they are somewhat connected).
So the IQueryBuilder
types make sense as they are for a different purpose (directly query the DB and converting parameters). But the column types are the same as the field types as the fields are just the abstraction of the DB types, meaning from an app perspective you would give the column type to the migration and to the ORM (the Entity class) and the class handles then the conversion between the DB and PHP.
It indicates that 'bigint', 'smallint' and 'text' would be accepted, but settype( will break?
Good point I think we should fix this here!
As mentioned on the other part it "dropped" the short forms bool and int
Only for psalm, it still works so does not break. I do not think it makes sense to add arbitrary aliases, no?
Also array and double are no longer?
Well there is only float
in doctrine and for PHP it makes no difference as float
and double
are the same in PHP.
So double
is just again an alias not available on doctrine. Yet it still will work and not break (only psalm will complain).
For array
I am not sure, I guess it would be json
, no? I do not see any other type that can be mapped to array
with doctrine for columns. But also this is not hard breaking as settype still will work.
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.
We also could have just added more types, but then we end up with 3 different type sources for the same task (mapping PHP -> DB types).
With this way you could even think further and add attributes to the Entity
properties to define types for automatic conversion (and if you like the ORM way then even migrations could be created from this).
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.
We already have 3 different mapping for db types:
OCP\DB\Types
,IQueryBuilder
and the migration column types.
Not sure what "migration column types" is? Migrations should use OCP\DB\Types
…
OCP\Migration\Attributes\ColumnType
TIL. Sounds like that tries to be a replacement for OCP\DB\Types
. Either it should be dropped again, or it needs to be extended with the change of this PR.
Should we deprecate OCP\DB\Types
then? We don't need 2 things trying to do the same thing, because one will always be the neglected sibling (as we just learned here).
Then for now let's make sure all \OCP\DB\Types
are supported by the Entity.
And we add a small psalm/type-hint for the old deprecated simple strings int|bool|double
and still map them to their new counterparts.
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 we deprecate OCP\DB\Types then?
Not sure the OCP\Migration\Attributes\ColumnType
is very specific also the namespace... It is a nice enum, but I think the namespace is confusing, so maybe the other way round?
Then for now let's make sure all \OCP\DB\Types are supported by the Entity.
Makes sense, thank you for your feedback!
Summary
This adds support for all Doctrine supported types, for the column types only the immutable variants needed to be added. But especially those types are the important ones, as our Entity class works by detecting changes through setters. Meaning if it is mutable, changes like
$entity->date->modfiy()
can not be detected, so the immutable types make more sense here.Similar the parameter types needed to be added.
Enity
andQBMapper
needed to be adjusted so they support (auto map) those types, required when insert or update an entity.Also added more tests, especially to make sure the mapper really serializes the values correctly.
Checklist