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

PDO : add method getColumnMeta #6109

Closed
wants to merge 3 commits into from

Conversation

salim-bahram
Copy link

@salim-bahram salim-bahram commented Jul 24, 2023

Q A
Type improvement
Fixed issues

Summary

@salim-bahram
Copy link
Author

salim-bahram commented Jul 24, 2023

Description :
The need we have is to recover the metadata of a column in a query. Before the version 3 , we was using the getColumnMeta method, but it was removed in the version 3.

So we need to recover the method getColumnMeta as we had it in the version 2.

This merge may handle the same problem that the ticket #3534.

@derrabus derrabus changed the base branch from 3.6.x to 3.7.x July 24, 2023 15:03
Copy link
Member

@derrabus derrabus left a comment

Choose a reason for hiding this comment

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

I'm against this change in its current form for multiple reasons:

  • The description does not explain why this change has been made.
  • The abstraction is leaky: We expose a data structure specific to PDO that other drivers would have to emulate.
  • Implementations for non-PDO drivers are missing.
  • Not a single test has been written for this feature.
  • The final keyword has been removed from multiple classes and various internal properties were switched to protected without any need.

src/Driver/IBMDB2/Result.php Outdated Show resolved Hide resolved
src/Driver/IBMDB2/Result.php Outdated Show resolved Hide resolved
/**
* Returns the column information.
*/
public function getColumnMeta($index): array;
Copy link
Member

Choose a reason for hiding this comment

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

This is a breaking change: We cannot add new methods to existing interfaces without breaking userland implementations.

@salim-bahram
Copy link
Author

salim-bahram commented Jul 24, 2023

Thank you for your comments @derrabus.

You were right , the final attribute and the protected have not to be removed, it was because of previous tests.

The need we have is to recover the metadata of a column in a query. Before the version 3 , we was using the getColumnMeta method, but it was removed in the version 3.

So we need to recover the method getColumnMeta as we had it in the version 2.

@salim-bahram
Copy link
Author

I will write tests if the idea is approved.

@derrabus
Copy link
Member

Thank you for the heads up. I'm afraid, "I'm adding the method because it had been removed" is not really enough. The method had been removed because we stopped extending PDO. Simply undoing this change would reintroduce the leaky abstraction that we've just gotten rid of.

The need we have is to recover the metadata of a column in a query.

  • Why do you have that need?
  • What kind of metadata do you need?
  • Can we find a good abstraction for that metadata?
  • Can we implement that abstraction in a way that non-PDO drivers could deliver that metadata as well?

This merge may handle the same problem that the ticket #3534.

That issue is about exposing the native result object so that functionality can be accessed that we don't provide an abstraction for. Accessing column metadata was only one motivation behind that, so your PR would not entirely solve that issue.

@derrabus derrabus marked this pull request as draft July 24, 2023 21:42
@salim-bahram
Copy link
Author

salim-bahram commented Jul 25, 2023

Thank you for your answers.

For more details, wa are using symfony with doctrine, and we were not using object in all our application. Sometimes, when the queries needed a huge quantity of data, we use mysql queries without using objects.
But the problem we had was that the results weren't with the good types. For example, the decimal and integers were returned as string.
So we need to convert this results in the good type.
I know that it's not the good way to use doctrine, but we could do it with the version 2 of doctrine as we had the type of each column in its metadata by pdo with the function getColumnMeta which is missing in the version 3.
So we can't change the version of doctrine, because we will not have the results in the good types.
Do you understand our problem ?
Have you any other solution without modify the dbal library ?
Thank you for your help @derrabus.

@derrabus
Copy link
Member

For example, the decimal and integers were returned as string.

PHP does not have an equivalent of the decimal type, so strings are fine here. Note that casting decimals to float may cause a loss in precision due to rounding errors. If a float is actually what you want, you should use a float or double in MySQL instead.

And PDO_mysql should return MySQL integers and floats as PHP integers and floats nowadays. I think, this has been improved in PHP 8.0.

So we need to convert this results in the good type.

Why do you need that kind of guesswork? If I send a query to a database server, e.g.

SELECT my_int_column FROM my_table;

Why do I need any guesswork to determine what columns I get and which types they have? My example may be trivial, but what I've said applies to even the most complex queries: I as the author of the query know that I've asked the server for, so nothing that the server returns should be a surprise.

The only exception I can think of if that the SQL itself is user input.

with the version 2 of doctrine as we had the type of each column in its metadata by pdo

Okay, so it's only about the type information. I believe it would be a great improvement if our results would expose information on their columns and types in a documented and portable way so that we can implement it across all drivers. But that's more than just dumping the PDO metadata.

So, my question is: After everything that I told you, do you still believe that you need type information on your results? And if so, do you want to work on a concept and implementation for an abstraction layer that works on all drivers and not just PDO_mysql?

@salim-bahram
Copy link
Author

I would like it working without any conversion.
Do you mean that we must use pdo_mysql instead of doctrine ? Or with doctrine ?
When we have the types it's more simple for us. For example :
case 'TINY':
return (bool) $value;
case 'DATETIME':
$date = new DateTime($value);
return $date->format('c');
If it's possible without getting the types, it's what i'm looking for.
Thank you for help.

@derrabus
Copy link
Member

If it's possible without getting the types, it's what i'm looking for.

It is possible without "getting the types" because you as the author of the SQL query should know exactly which columns that query will yield.

@salim-bahram
Copy link
Author

Ok, so for every query, i have to put the type i want.
As :
$query = 'SELECT user_date_creation FROM users WHERE email = ...;';
$result = ...;
$result['user_date_creation'] = (new DateTime($result['user_date_creation']))->format('c');
Is it the solution you are talking about @derrabus ?
Thank you.

@derrabus
Copy link
Member

Pretty much. It's your database, it's your query. You should be able to tell what the type of the result column user_date_creation is. You should not need to guess anything.

@salim-bahram
Copy link
Author

The problem is that we have to do this for every query.
So far, we call a trait which to the work with a common function for all query, without handle each query individually.
I understand your solution, but it was no what we are looking for.
Thank you for your help and your time @derrabus

@derrabus
Copy link
Member

All right. Shall we close this PR then?

@salim-bahram
Copy link
Author

Currently, we can.
I will reflect more about it.

@derrabus derrabus closed this Jul 25, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants