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

Automatic object to Expression conversion #420

Closed
milo opened this issue Apr 22, 2022 · 3 comments
Closed

Automatic object to Expression conversion #420

milo opened this issue Apr 22, 2022 · 3 comments

Comments

@milo
Copy link
Collaborator

milo commented Apr 22, 2022

Would be nice to have a capability of automatic object to Dibi expression conversion, similar to BackedEnum conversion.

Explanation

Let's start by date and time. Poor PHP support for separated date and time is one of the pain. Basic classes Date and Time are missing, everyting is DateTime and it is not allowed to implement DateTimeInterface. As a result, one has to specify data type for data modification in database:

$insert = [
   'name' => 'Milo',
   'dateOfBirth%d' => new DateTimeImmutable(...),  # <-- the %d modifier is required
]; 

The %d is always required. And in simple queries the ? modifier can't be used.

Next issue is a fetch-and-push-back workflow. Row is fetched from database and cannot be inserted back without modification. I mean:

$row = $db->query('SELECT name, dateOfBirth FROM ...')->fetch();
$db->insert('...', $row);  # fails

Inserting back fails, because the value for column dateOfBirth is a DateTime object and it is converted to Y-m-d H:i:s string which is not accepted by database as a value for date type.

This applies for all value objects. For example, I have custom implementations for IPv4Address, IPv4Subnet, dtto for IPv6..., EmailAddress and few more.

PHP to SQL

Edit: this part is solved by #432

There was an issue #385 proposing to make Dibi\Expression an interface. I proposed to make a new interface with method toDibiExpression(): Expression. I think that both proposes are invalid. A value object should not be aware of Dibi layer.

I propose to create a new interface which will accept object and it will translate it into Dibi expression.

namespace Dibi;

interface ObjectTranslator
{
    function translate(object $object): ?Expression;
}

Such translator will be setter-injected into Dibi connection:

$db = new Dibi\Connection;
$db->setObjectTranslator(new MyTranslator);

And when Dibi\Translator hits the object of unknown class, it will call ObjectTranslator::translate().

SQL to PHP

(note: I'm not sure about this part I just want to mention that)

Data type translation of fetched rows now works fine. I think that row factory is sufficient. But there is a space for improvement.

Row fetched from a database layer is a set of scalars and dibi tries to convert them as best as possible. If it does not work for one, type can be set manually:

$db->query(...)->setType('column', Type::INT);

Maybe this can be extended to Type::OBJECT:

$db->query(...)->setType('column', Type::OBJECT, MyClass::class);

The ObjectTranslator will be extended by another method:

interface ObjectTranslator
{
    function hydrate(mixed $value, string $class): object;
}

Conclusions

It is all about PHP <-> SQL values translations and I think that this solution is clean enough. There are naming questions. Maybe there can be two separate interfaces for PHP -> SQL and SQL -> PHP.

If you think that whole concept is not completely wrong, I'll prepare proof of concept pull request at least for the 1st part, the PHP to SQL translation.

@eydun
Copy link

eydun commented May 29, 2022

Looking forward to this improvement 👍

milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
@milo milo mentioned this issue Nov 22, 2022
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Nov 22, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
dg pushed a commit that referenced this issue Dec 20, 2022
Object translator allows to translate any object passed to Translator into Dibi\Expression.
milo added a commit to milo/dibi that referenced this issue Jan 2, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Feb 2, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Feb 2, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
@milo
Copy link
Collaborator Author

milo commented Feb 4, 2023

I'm closing this issue as a PHP object to Dibi expression is solved by #432

The second case - fetched scalar type to PHP object hydration can be solved by row factory for now and I'm satisfied with that. Maybe I'll open PR for some improvements later.

@milo milo closed this as completed Feb 4, 2023
dg pushed a commit that referenced this issue Feb 27, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
@eydun
Copy link

eydun commented Jul 21, 2023

Hoping there soon will be a new dibi release with this feature 👍

dg pushed a commit that referenced this issue Aug 5, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 5, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 5, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 5, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 5, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 9, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 9, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 9, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 9, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
dg pushed a commit that referenced this issue Aug 9, 2023
The Translator is now capable to translate objects into Expression via object translators registered by the Connection.
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

No branches or pull requests

2 participants