Skip to content
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

Add failing tests and TODOs for doctrine types #342

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Seldaek
Copy link
Contributor

@Seldaek Seldaek commented May 18, 2022


$stmt = $conn->prepare('SELECT count(*) AS c FROM typemix WHERE c_datetime=:last_dt');
$result = $stmt->execute(['dt' => new \DateTime()], ['dt' => Types::DATETIME_IMMUTABLE]);
// TODO should probably fail as DateTime is passed to a DATETIME_IMMUTABLE type
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think doctrine will fail though, the distinction between datetime/datetime_immutable is only made there when deserializing data from DB back into PHP AFAIK, so maybe we can let it go through..

@staabm
Copy link
Owner

staabm commented May 18, 2022

thank you!

don't let you mislead by the current build errors.. they seem to be happening also on master - as I realized yesterday.

I need to investigate what needs to be done about them.

@Seldaek
Copy link
Contributor Author

Seldaek commented May 18, 2022

See e8b4e64 for a demo of what could be done to solve what I said in #339

Partially addresses #278 - but the way I see it, in QuerySimulation::simulateParamValueType you don't have access to the param types argument, only to the parameter themselves?

I mean PDO::exec($query, $params, $paramTypes) <- this param types arg

Without access to that we can serialize the datetime to a Y-m-d H:i:s format, but it won't be always correct, as if you pass Doctrine\DBAL\Types\Types::DATE for ex then it should use Y-m-d only. And strictly speaking we should only simulate/serialize DateTime objects if the appropriate Type is passed in $paramTypes. Otherwise it's unlikely to be a bug if you have a DateTime in there as it will fail at runtime.

I don't know if this is the best/correct way to do this though, and I'm completely lost as to how to resolve the bound types further, but hopefully it is clear enough that you may be able to go forward with this? Otherwise as I said in #339 just merging that fix (e.g. the first two commits here) would already be an improvement altho it would be very permissive and perhaps not catch mistakes.

@staabm
Copy link
Owner

staabm commented May 18, 2022

thank you so far. I will have a closer look when time allows.

@staabm
Copy link
Owner

staabm commented May 18, 2022

this is looking really good already.

I will merge #339 for a short-term fix to unblock you in your projects and will have a deeper look into this PR here for a future release.

the failling test-cases are really valueable, so thank you.

@staabm
Copy link
Owner

staabm commented May 18, 2022

memo for myself: PDO has the same bound parameter semantics

public function customTypeParameters(Connection $conn, int $adaid)
{
$stmt = $conn->prepare('SELECT count(*) AS c FROM typemix WHERE c_datetime=:last_dt');
$result = $stmt->execute(['dt' => new \DateTime()], ['dt' => Types::DATETIME_MUTABLE]);
Copy link
Owner

@staabm staabm May 18, 2022

Choose a reason for hiding this comment

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

does doctrine allow to pass in a DateTime object without also giving a parameter-type as a 2nd arg?

or should phpstan-dba error when arg1 is DateTime and arg2 is either missing or not equal to Types::DATETIME_MUTABLE?

edit: I see, there are a few types arround dates in doctrine: https://github.com/doctrine/dbal/blob/007223cfe9dc5cf37420a6a8d8ecd48d520b69d4/src/Types/Types.php#L18-L24

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if it lets you do it without the param type, but I'd think not.

Comment on lines +229 to +230
$stmt = $conn->prepare('SELECT count(*) AS c FROM typemix WHERE c_datetime=:last_dt');
$result = $stmt->execute(['dt' => new \DateTime()], ['dt' => Types::DATETIME_IMMUTABLE]);
Copy link
Owner

Choose a reason for hiding this comment

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

should this test also use $conn->executeQuery() instead? it seems there is no prepare+execute api including bound-parameter-types...?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

DBAL supports this on all connection methods it seems https://github.com/doctrine/dbal/blob/3.3.x/src/Connection.php#L529

Also on quote https://github.com/doctrine/dbal/blob/3.3.x/src/Connection.php#L811

So I guess ideally this would be supported on all the things, but executeStatement/executeQuery would be the must-haves IMO as it's the lowest common denominator and the rest is kinda decorating this.

@staabm
Copy link
Owner

staabm commented May 23, 2022

just to let you know. this is not forgotten, but I will do some internal cleanup before starting again on this one

@Seldaek
Copy link
Contributor Author

Seldaek commented May 23, 2022

No worries and no rush really

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants