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
Walkable queries #81
Walkable queries #81
Conversation
Added phpdoc, or fixed obvious errors.
Allows stateless executors (almost), thus nested executors.
Allows storage of non string references.
Allows to walk query results, and run a step for each result: ``` - mode: location type: query match: query_type: some_query_type collection: my_collection walk: # run another query on each location - mode: location type: query match: query_type: get_x_children parameters: location_id: "@=collection_item(my_collection).id" collection: some_other_collection walk: - ... # Do something to the location - mode: update type: location match: location_id: "@=collection_item('my_collection')" # .. ```
very interesting!! |
@@ -100,7 +100,7 @@ public function execute(MigrationStep $step) | |||
|
|||
$previousUserId = $this->loginUser(self::ADMIN_USER_ID); | |||
try { | |||
$output = $this->$action(); | |||
$output = $this->$action($step->dsl); |
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.
mmm, ce n'est pas dejà dispo qq part ?
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.
It is available, but we can't use a stateful variable (explained that in the commit message). Since all executors have the DSL stored as a property, changes by one affect the DSL read by the other layers. And bam.
It is kind of a big change, but I don't see big counterparts.
I doubt that this failure is on me: https://travis-ci.org/kaliop-uk/ezmigrationbundle/jobs/171643923 :-) But a little problem I have here: this implementation requires QueryTypes. And those were added in eZ Platform, meaning kernel >= 6.0. I guess I must disable the feature for earlier versions somehow ? |
Yeah, the Travis failure on eZ6 is weird, I pin it down to Travis caching some bits of Sf somehow... it makes little sense at first sight, as in theory it fails with an SF3 error, but we are running that test case on SF2.8... So I just tagged testing on eZ6 as 'allow fail' for now, while I carve out time for a deeper investigation. As for the need to be able to run the test suite on eZP versions starting 2014.3 yes, please :-) |
ps: as a side note: it was my original intention to allow the existing 'matcher' classes to be able to work on an array of conditions passed in, not just a single one (in short: turn matchers into query builders). I never came around to implementing that. At first sight, it seems that your code does something similar but in a different way... did you take a look at extending the matchers ? |
I first started by implementing queries on matchers, and it turned out to be tedious and repetitive. It requiredwhich seem far from efficient. Rather than heavily changing the existing, this implementations sits around it. I found out that there are a few advantages to this structure:
The nesting part is really important with the use-case i'm working with, and I think that it allows for complex migrations with the comfort and ease of use of yaml. |
I see what you mean. |
QueryTypes: no, they're not. That's why I was hinting about earlier :) |
ps: could you add an example DSL in the doc folder ? |
Hi As for QueryTypes, they could be backported somewhere like EzCoreExtraBundle. I intended to do so sooner or later. |
Sorry for my ignorance, but what is |
It is how collections are set as references, to be used later on with |
public function addExecutor(ExecutorInterface $executor) | ||
{ | ||
foreach($executor->supportedTypes() as $type) { | ||
$this->executors[$type] = $executor; |
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.
Shouldn't this be $this->executors[$type][]
?
* @param $searchResult | ||
* @return boolean | ||
*/ | ||
protected function setReferences($args) |
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.
Why not using proper arguments here?
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Reference; | ||
|
||
class QueryManagerCompilerPass implements CompilerPassInterface |
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.
Please briefly explain what this compiler pass is meant for
|
||
ez_migration_bundle.expression_language: | ||
class: Symfony\Component\ExpressionLanguage\ExpressionLanguage | ||
lazy: true |
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.
Why lazy?
*/ | ||
public function process(ContainerBuilder $container) | ||
{ | ||
if ($container->has('ez_migration_bundle.executor.query_manager') && $container->has('ez_migration_bundle.migration_service')) { |
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.
Better using return asap pattern here :-)
function() { | ||
throw new \Exception('ref function does not support compilation'); | ||
}, | ||
function($foo, $identifier) { |
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.
$foo
represents the variables from the expression context. This is actually a hash, identical to what we pass to a twig view when rendering it.
So we'd better name it $variables
and type hint it as array
😉
|
||
protected function getSearchService() | ||
{ | ||
return $this->repository->getSearchService(); |
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.
Is this really needed?
{ | ||
foreach ($this->matchers as $matcher) { | ||
$result = $matcher->match($dsl['match']); | ||
if (count($result) == 1) { |
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.
What if count is > 1
?
$this->referenceResolver->addReference('collection_' . $collection, $value, true); | ||
} | ||
|
||
protected function getQuery($dsl) |
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.
PHPDoc please 😃
use Symfony\Component\ExpressionLanguage\ExpressionFunction; | ||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage; | ||
|
||
class QueryManager extends RepositoryExecutor |
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.
What about QueryExecutor
instead?
Besides, class name isn't quite self-explanatory. Maybe a phpdoc comment is needed 😉
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.
OK forget it, it's perfectly inline with other managers 😊
Allows usage of '%parameter%' in any field that supports references.
About the QueryType class not existing in older kernels: what if we split off this PR into its own bundle & repo, and only try to push into the migrationbundle the minimal changes required to support it? Apart from solving the requirements problem, I think that there might be other, smaller benefits to that approach:
|
Status update:
|
Status update: matching based on QueryType has been implemented, and will be in 5.14. |
This adds support for a
query
migration type, that walks over results from a query, and apply another migration to them.This allows operations such as multi-criteria selection of a set of items with another operation on each result. The Expression Language is used to map parameters from the query to migration parameters, with a
collection_item
function that has each current item of each iteration.Usage example: for a set of content items, it adds locations to them below items from a relation list field (uses a custom function), and delete the former main location:
Custom expression language functions, such as
relatedContentIds
, can be registered with a service tag.TODO
QueryType
problem. The feature did not exist in older kernel versions. Needs to be handled cleanly (this is why Travis fails)