- Issue created by @effulgentsia
- πΊπΈUnited States bradjones1 Digital Nomad Life
Laravel has a similar database abstraction layer and supports this through their own implementation of
->
operator (abstracted out for the various supported db drivers, which intersects with our own) - see https://laravel.com/api/8.x/Illuminate/Database/Query/Builder.html#metho... and https://laravel.com/docs/10.x/queries#json-where-clausesTheir equivalent to our DB drivers (now in separate modules) appear to be "grammars". They extend a common Grammar class and there is a lot of special-casing e.g. for Postgres that we could likely draw a lot of inspiration from or directly lift. Laravel is MIT licensed so no issues there.
What we would want to decide on early-on is whether this is a job for
::condition()
in the query builder or if we wanted to take a Laravel-like approach and add JSON-specific/aware conditions. I like this idea for the reason that it makes explicit the requirements for and syntax of the parameters. I'm still wrapping my head around the idea that there is depth/dimension to these kinds of queries, as opposed to the atomic single-column/value construct of a traditional SQLWHERE
clause. This might also allow us to avoid changing method signatures and doing deprecation dances.Elsewhere in the PHP ORM ecosystem, there is an extension library for Doctrine, https://github.com/ScientaNL/DoctrineJsonFunctions, but it doesn't appear to provide a true abstraction layer.
When it comes to entity queries (which would come after we get these foundational building blocks done) we will need to address how to merge these concepts with our DBAL's chaining feature. E.g.,
->condition('json_field_name.$.json.path.to.subelement', 'value', 'operator')
. This is kinda like how you can doentity_reference_field.entity.that_entities_field.property
. We'd need to hash that out when the time comes, and I think there is also some greenfield development/policy to be forged on whether we want to support some of the novel operators available to JSON fields that don't have a standard SQL equivalent.I think we do need to additionally accomplish in this issue:
Identify operators to be supported when testing a jsonpath's value. The current
ConditionInterface::condition()
docs state:* @param string|null $operator * The operator to use. Supported for all supported databases are at least: * - The comparison operators =, <>, <, <=, >, >=. * - The operators (NOT) BETWEEN, (NOT) IN, (NOT) EXISTS, (NOT) LIKE. * Other operators (e.g. LIKE, BINARY) may or may not work. Defaults to =.
which seems easy enough to accomplish. We might even say that an MVP for initial core support is to not at all support things like
JSON_CONTAINS()
and similar. Now that the db drivers are abstracted into modules, this kind of thing can be sandboxed in contrib-land and then added to core, for instance.