Skip to content

Commit

Permalink
Merge pull request #143 from GrandLTU/relations
Browse files Browse the repository at this point in the history
Relations
  • Loading branch information
Mindaugas Barysas committed Feb 5, 2015
2 parents 36a776f + f7ef945 commit 64364eb
Show file tree
Hide file tree
Showing 30 changed files with 740 additions and 352 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/**
* Helper base class for adding MySQL parameters to the given definition.
*/
abstract class AbstractMySqlPass
abstract class AbstractExtractionDescriptorPass
{
/**
* @param ContainerBuilder $container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,24 @@
use Symfony\Component\DependencyInjection\Reference;

/**
* Adds services tagged as sql relation to relations collection.
* Adds services tagged as sql relation to descriptors collection.
*/
class SqlRelationPass extends AbstractMySqlPass implements CompilerPassInterface
class ExtractionDescriptorPass extends AbstractExtractionDescriptorPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('ongr_connections.sync.relations_collection')) {
if (!$container->hasDefinition('ongr_connections.sync.extraction_collection')) {
return;
}
$triggersManagerDefinition = $container->getDefinition('ongr_connections.sync.relations_collection');
foreach ($container->findTaggedServiceIds('ongr_connections.sql_relation') as $id => $tags) {
$collectionDefinition = $container->getDefinition('ongr_connections.sync.extraction_collection');
foreach ($container->findTaggedServiceIds('ongr_connections.extraction_descriptor') as $id => $tags) {
$definition = $container->getDefinition($id);
$definition->addMethodCall('setName', [$id]);
$this->addParameters($container, $definition);
$triggersManagerDefinition->addMethodCall('addRelation', [new Reference($id)]);
$collectionDefinition->addMethodCall('addDescriptor', [new Reference($id)]);
}
}
}
4 changes: 2 additions & 2 deletions ONGRConnectionsBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace ONGR\ConnectionsBundle;

use ONGR\ConnectionsBundle\DependencyInjection\Compiler\SqlRelationPass;
use ONGR\ConnectionsBundle\DependencyInjection\Compiler\ExtractionDescriptorPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

Expand All @@ -27,6 +27,6 @@ public function build(ContainerBuilder $container)
{
parent::build($container);

$container->addCompilerPass(new SqlRelationPass());
$container->addCompilerPass(new ExtractionDescriptorPass());
}
}
8 changes: 4 additions & 4 deletions Resources/config/extractor.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
parameters:
ongr_connections.extractor.doctrine_extractor.class: ONGR\ConnectionsBundle\Sync\Extractor\DoctrineExtractor
ongr_connections.extractor.passthrough_extractor.class: ONGR\ConnectionsBundle\Sync\Extractor\PassthroughExtractor
ongr_connections.sync.relations_collection.class: ONGR\ConnectionsBundle\Sync\Extractor\Relation\RelationsCollection
ongr_connections.sync.extraction_collection.class: ONGR\ConnectionsBundle\Sync\Extractor\Descriptor\ExtractionCollection

services:
ongr_connections.sync.extractor.doctrine_extractor:
class: %ongr_connections.extractor.doctrine_extractor.class%
calls:
- [ setRelationsCollection, [ @ongr_connections.sync.relations_collection ] ]
- [ setExtractionCollection, [ @ongr_connections.sync.extraction_collection ] ]
- [ setConnection, [ @database_connection ] ]
- [ setStorageFacility, [ @ongr_connections.sync.sync_storage ] ]
- [ setContainer, [ @service_container ] ]
Expand All @@ -18,5 +18,5 @@ services:
- [ setStorageFacility, [ @ongr_connections.sync.sync_storage ] ]
- [ setContainer, [ @service_container ] ]

ongr_connections.sync.relations_collection:
class: %ongr_connections.sync.relations_collection.class%
ongr_connections.sync.extraction_collection:
class: %ongr_connections.sync.extraction_collection.class%
7 changes: 3 additions & 4 deletions Resources/config/extractor_relations.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
parameters:
# Sql relations classes
ongr_connections.sql_relations.simple_relation.class: ONGR\ConnectionsBundle\Sync\Extractor\Relation\SimpleSqlRelation
ongr_connections.sql_relations.composed_relation.class: ONGR\ConnectionsBundle\Sync\Extractor\Relation\ComposedSqlRelation
ongr_connections.sql_relations.table_relation.class: ONGR\ConnectionsBundle\Sync\Extractor\Relation\JoinStatement
# Sql descriptors classes
ongr_connections.extractor.descriptor.class: ONGR\ConnectionsBundle\Sync\Extractor\Descriptor\ExtractionDescriptor
ongr_connections.extractor.join_relation.class: ONGR\ConnectionsBundle\Sync\Extractor\Descriptor\JoinRelation

140 changes: 140 additions & 0 deletions Resources/doc/sync/descriptors/descriptors.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
Descriptors
===========

Extraction descriptors are special classes that tell extractor which fields/tables to watch for changes.

By default, all services tagged with a ``{ name: ongr_connections.extraction_descriptor }`` are added to a single service
called ``ongr_connections.sync.extraction_collection``, which later on can be passed as a parameter for
an `extractor <../extractor/extractor.rst>`_ via ``setExtractionCollection`` method.

When `extractor <../extractor/extractor.rst>`_ looks for changes, it iterates through the descriptors -
executing each descriptor as to mark down which changes in the database are relevant.

NOTE: Only ``DoctrineExtractor`` supports descriptors so far.

Example extractor configuration:

.. code-block:: yaml
# Extractor service.
ongr_connections.sync.extractor.doctrine_extractor:
class: ONGR\ConnectionsBundle\Sync\Extractor\DoctrineExtractor # Extractor class.
calls:
- [ setExtractionCollection, [ @ongr_connections.sync.extraction_collection ] ] # Sql relation collection.
- [ setConnection, [ @database_connection ] ] # Database collection.
- [ setStorageFacility, [ @ongr_connections.sync.sync_storage ] ] # Sync storage provider.
# Relation collection service must be configured in order to use it.
ongr_connections.sync.extraction_collection:
class: ONGR\ConnectionsBundle\Sync\Extractor\Descriptor\ExtractionCollection
Example simple extraction Descriptors setup:

.. code-block:: yaml
services:
# Descriptor for category creation.
my_project.extractor.descriptors.category.create:
class: %ongr_connections.extractor.descriptor.class%
arguments: [my_categories, C, NEW.categories_id, 1, category]
tags:
- { name: ongr_connections.extraction_descriptor } # This tag is used to collect all descriptors.
# Descriptor for category update.
my_project.extractor.descriptors.category.update:
class: %ongr_connections.extractor.descriptor.class%
arguments: [my_categories, U, NEW.categories_id, 1, category]
tags:
- { name: ongr_connections.extraction_descriptor } # This tag is used to collect all descriptors.
# Descriptor for category deletion
my_project.extractor.descriptors.category.delete:
class: %ongr_connections.extractor.descriptor.class%
arguments: [my_categories, D, OLD.categories_id, 1, category]
tags:
- { name: ongr_connections.extraction_descriptor } # This tag is used to collect all descriptors.
..
Extraction Descriptor constructor arguments are as follows:

.. code-block:: php
/**
* @param string $table Table name to hook on.
* @param string $type Trigger and default job type C - create, U - update, D - delete.
* @param int|null $idField Source for document id.
* @param int|null $updateType Partial update - 0, full update - 1.
* @param string|null $documentType Type of target document.
* @param array $trackFields Array of table fields to track, all using default priority.
* @param string|null $jobType C - create, U - update, D - delete.
*/
..
Last two parameters can and should be left undefined, as they are to be deprecated in near future.

Cascading changes
-----------------

There are classes that help implement cascading data changes, e.g. if you have changed the name of the
category, you also have to update all the products which use said categories' name.

``Extractor\Descriptor\JoinRelation`` class does exactly that: you can attach it to a descriptor and when changes are
detected, `extractor <../extractor/extractor.rst>`_ calls the relations and marks related documents as changed.

If ``$documentType`` is left undefined document itself will not be marked as changed but related items will.

Example cascading change configuration:

.. code-block:: yaml
services:
#
# Create and delete descriptors omitted for brevity.
#
my_project.extractor.descriptors.category.update:
class: %ongr_connections.extractor.descriptor.class%
arguments: [my_categories, U, NEW.categories_id, 1, category]
tags:
- { name: ongr_connections.extraction_descriptor }
calls:
- [ addRelation, [ @my_project.extractor.descriptors.product.join.category ] ] # Call this relation if category is updated.
my_project.extractor.descriptors.product.join.category:
class: %ongr_connections.extractor.join_relation.class%
arguments: [my_products_to_categories AS product_to_category, product_to_category.products_id, product_to_category.categories_id=NEW.categories_id, product, U, 1]
..
Example cascading change but not effecting triggered item:

.. code-block:: yaml
services:
#
# Create and delete descriptors omitted for brevity.
#
my_project.extractor.descriptors.category.update:
class: %ongr_connections.extractor.descriptor.class%
arguments: [my_categories, U, NEW.categories_id]
tags:
- { name: ongr_connections.extraction_descriptor }
calls:
- [ addRelation, [ @my_project.extractor.descriptors.product.join.category ] ] # Call this relation if category is updated.
my_project.extractor.descriptors.product.join.category:
class: %ongr_connections.extractor.join_relation.class%
arguments: [my_products_to_categories AS product_to_category, product_to_category.products_id, product_to_category.categories_id=NEW.categories_id, product, U, 1]
..
The arguments for ``JoinRelation`` are as follows:

.. code-block:: php
/**
* @param string $table Related table name.
* @param string $documentId Document id.
* @param string $searchCondition Escaped condition to create where sentence.
* @param string $documentType Target document type.
*/
..
4 changes: 2 additions & 2 deletions Resources/doc/sync/extractor/extractor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ There are two extractors provided by this bundle:
a very simple extractor which depends on the storage to provide only relevant data. Provided as an example only, it is
not really used anywhere.
- ``DoctrineExtractor`` - is `the` extractor in ConnectionsBundle. This extractor relies on
`Sql relations <../relations/sql_relations.rst>`_ to distinguish which diff is relevant. It also "sees" cascading
changes, provided the `JoinStatements <../relations/sql_relations.rst>`_ are configured correctly.
`descriptors <../descriptors/descriptors.rst>`_ to distinguish which diff is relevant. It also "sees" cascading
changes, provided the `JoinRelation <../descriptors/descriptors.rst>`_ are configured correctly.
120 changes: 0 additions & 120 deletions Resources/doc/sync/relations/sql_relations.rst

This file was deleted.

6 changes: 3 additions & 3 deletions Resources/doc/sync/sync.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ obtain a Diff object to be stored in `synchronization storage <storage/sync_stor
Data Sync Provide consume event listener service uses `Extractor <extractor/extractor.rst>`_ to parse the Diff object
and `Sync Storage Provider <storage/sync_storage.rst>`_ to write the ids of changed objects.

Extractor on its' own accord iterates through `SQL Relations <relations/sql_relations.rst>`_ to ensure that objects which are "watched" are
Extractor on its' own accord iterates through `Extraction Descriptors <descriptors/descriptors.rst>`_ to ensure that objects which are "watched" are
included in the change list.

Each SQL Relation iterates through `joint statements <relations/sql_relations.rst>`_ which ensure that the related objects
Each Descriptor iterates through `joint relations <descriptors/descriptors.rst>`_ which ensure that the related objects
are marked as changed as well.

There is no modify or finish event listener.
Expand Down Expand Up @@ -69,7 +69,7 @@ This bundle provides implementation which uses mysql database as synchronization
Configuration
~~~~~~~~~~~~~

See `SQL Relations documentation <relations/sql_relations.rst>`_ for information on how to configure what should be
See `Extraction Descriptors documentation <descriptors/descriptors.rst>`_ for information on how to configure what should be
included in continuous synchronization.

Sub-topics
Expand Down
2 changes: 1 addition & 1 deletion Sync/DiffProvider/Binlog/BinlogParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ protected function handleStart($line)
}

/**
* Handle SQL statements.
* Handle SQL relations.
*
* @param string $line
* @param string $type
Expand Down
Loading

0 comments on commit 64364eb

Please sign in to comment.