From 329a3d9d9c3e3b8855de74dda62d77f39d97cfb1 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Fri, 31 Jul 2020 15:07:38 +0100
Subject: [PATCH] Issue #2955442 by amateescu, plach, jibran, Berdir: Add a way
 to get all the tables in which a field is stored from TableMappingInterface

---
 .../Core/Entity/Sql/DefaultTableMapping.php   |  9 +++++
 .../Core/Entity/Sql/TableMappingInterface.php | 22 +++++++++++
 .../DefaultTableMappingIntegrationTest.php    | 37 +++++++++++++++++++
 3 files changed, 68 insertions(+)

diff --git a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
index fdced261c936..19ee7808d586 100644
--- a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
+++ b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
@@ -394,6 +394,15 @@ public function getFieldTableName($field_name) {
     return $result;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getAllFieldTableNames($field_name) {
+    return array_keys(array_filter($this->fieldNames, function ($table_fields) use ($field_name) {
+      return in_array($field_name, $table_fields, TRUE);
+    }));
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Entity/Sql/TableMappingInterface.php b/core/lib/Drupal/Core/Entity/Sql/TableMappingInterface.php
index 31c33854bdb8..d3971e66c2df 100644
--- a/core/lib/Drupal/Core/Entity/Sql/TableMappingInterface.php
+++ b/core/lib/Drupal/Core/Entity/Sql/TableMappingInterface.php
@@ -120,4 +120,26 @@ public function getFieldColumnName(FieldStorageDefinitionInterface $storage_defi
    */
   public function getFieldTableName($field_name);
 
+  /**
+   * Gets all the table names in which an entity field is stored.
+   *
+   * The returned table names are ordered by the amount of data stored in each
+   * table. For example, a revisionable and translatable entity type which uses
+   * core's default table mapping strategy would return the table names for the
+   * entity ID field in the following order:
+   * - base table
+   * - data table
+   * - revision table
+   * - revision data table
+   *
+   * @param string $field_name
+   *   The name of the entity field to return the tables names for.
+   *
+   * @return string[]
+   *   An array of table names in which the given field is stored.
+   *
+   * @throws \Drupal\Core\Entity\Sql\SqlContentEntityStorageException
+   */
+  public function getAllFieldTableNames($field_name);
+
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php
index 21fc13228909..0e5815ab7ae1 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php
@@ -77,6 +77,43 @@ public function testGetFieldTableName() {
     $this->assertEquals($this->tableMapping->getFieldTableName('multivalued_base_field'), $expected);
   }
 
+  /**
+   * @covers ::getAllFieldTableNames
+   */
+  public function testGetAllFieldTableNames() {
+    // Check a field that is stored in all the shared tables.
+    $expected = [
+      'entity_test_mulrev',
+      'entity_test_mulrev_property_data',
+      'entity_test_mulrev_revision',
+      'entity_test_mulrev_property_revision',
+    ];
+    $this->assertEquals($expected, $this->tableMapping->getAllFieldTableNames('id'));
+
+    // Check a field that is stored only in the base table.
+    $expected = ['entity_test_mulrev'];
+    $this->assertEquals($expected, $this->tableMapping->getAllFieldTableNames('uuid'));
+
+    // Check a field that is stored only in the revision table.
+    $expected = ['entity_test_mulrev_revision'];
+    $this->assertEquals($expected, $this->tableMapping->getAllFieldTableNames('revision_default'));
+
+    // Check a field that field that is stored in the data and revision data
+    // tables.
+    $expected = [
+      'entity_test_mulrev_property_data',
+      'entity_test_mulrev_property_revision',
+    ];
+    $this->assertEquals($expected, $this->tableMapping->getAllFieldTableNames('name'));
+
+    // Check a field that is stored in dedicated data and revision data tables.
+    $expected = [
+      'entity_test_mulrev__multivalued_base_field',
+      'entity_test_mulrev_r__f86e511394',
+    ];
+    $this->assertEquals($expected, $this->tableMapping->getAllFieldTableNames('multivalued_base_field'));
+  }
+
   /**
    * Tests DefaultTableMapping::getTableNames().
    *
-- 
GitLab