Problem/Motivation

Almost all methods provided by the Sql id map plugin trigger the creation of its map and message tables. The issue becomes noticable when plugins are initialized liberally, possibly even though their requirements are not fulfilled.

This issue often arises when contrib modules want to build a list of all migrations, either via drush migrate-status or by visiting the migrations overview, as provided by migrate_tools.

The core upgrade path will typically use either a Drupal 6 -or- a Drupal 7 instance, but not both. However, tables are created for all migrations, causing approximately double the amount of tables necessary, even though half the migrations are never executed. As these tables are not automatically removed upon uninstall (#2713327: Provide a way to remove migration tables (ID map etc.)), we should only create them when necessary.

Proposed resolution

Delay the creation of the mapping tables without affecting the method functionality.

CommentFileSizeAuthor
#59 interdiff-58-59.txt885 bytesAnonymous (not verified)
#59 2817833-59.patch9.58 KBAnonymous (not verified)
#58 interdiff-2817833-56-58.txt540 byteschiranjeeb2410
#58 2817833-58.patch9.48 KBchiranjeeb2410
#56 interdiff-2817833-52-56.txt591 byteschiranjeeb2410
#56 2817833-56.patch9.48 KBchiranjeeb2410
#52 interdiff-2817833-48-52.txt574 byteschiranjeeb2410
#52 2817833-52.patch9.53 KBchiranjeeb2410
#50 interdiff-2817833-48-50.txt501 byteschiranjeeb2410
#50 2817833-50.patch9.46 KBchiranjeeb2410
#48 2817833-48.patch9.42 KBjofitz
#48 interdiff-40-48.txt617 bytesjofitz
#46 2817833-46.patch561 byteschiranjeeb2410
#41 interdiff-2817833-38-40.txt10.92 KBbhanuprakashnani
#40 2817833-40.patch9.29 KBjofitz
#38 2817833-38.patch18.94 KBaleevas
#36 2817833-36.patch9.27 KBjofitz
#36 interdiff-21-36.txt3.56 KBjofitz
#21 2817833-21-complete.patch5.98 KBjofitz
#21 2817833-21-test_only.patch1.15 KBjofitz
#17 2817833-17.patch4.82 KBjofitz
#14 2817833-14.patch4.85 KBjofitz
#9 interdiff-2-9.txt1.41 KBckaotik
#9 delay_sql_map_init-2817833-9.patch4.86 KBckaotik
#6 delay_sql_map_init-2817833-6.patch4.54 KBsvendecabooter
#2 delay_sql_map_init-2817833-2.patch4.5 KBckaotik
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ckaotik created an issue. See original summary.

ckaotik’s picture

Attached missing patch.

Status: Needs review » Needs work

The last submitted patch, 2: delay_sql_map_init-2817833-2.patch, failed testing.

iMiksu’s picture

Added related issue.

ckaotik’s picture

Hrm, it seems the test fails are all caused by \Drupal::database() not working when constructing the object for the tests. It does work when using in a Drupal, though.
Don't know how to go and fix this - do we need to adjust the tests? Or is there a better way to handle it?

svendecabooter’s picture

Status: Needs work » Needs review
FileSize
4.54 KB

In the tests, the class \Drupal\Tests\migrate\Unit\TestSqlIdMap is used, which extends the class core/modules/migrate/src/Plugin/migrate/id_map/Sql.php you are changing in this patch.

TestSqlIdMap already sets the property $this->database to a SQLite test database, so \Drupal::database() would never have to be called in the tests.
However in the patch you are explicitly reassigning the database property to \Drupal::database() in Sql class.

This issue can be solved by adding a check whether the database property is already set.

I wonder why the database can't be provided through dependency injection in the Sql plugin class. That would make more sense, but there's probably a valid reason not to do it... I'm not unsure of how this plugin works in detail...

Attached is an updated patch that should no longer break the tests.
Not sure if the test coverage will need to be changed, based on the changed logic in this patch though.

ckaotik’s picture

Thanks for the updated patch :) That explains why the isset check was in there originally.

I wonder why the database can't be provided through dependency injection in the Sql plugin class.

I was also wondering about this. Originally, getDatabase was doing the assignment. When there's no real reason to not use dependency injection, I'd say we should probably use DI.

mikeryan’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Just a couple of nits - and, of course, we need a test.

  1. +++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php
    @@ -717,12 +714,19 @@ public function messageCount() {
    +  protected function countHelper($status = NULL, $table = NULL) {
    

    Update docs to reflect $status is now optionally an array.

  2. +++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php
    @@ -717,12 +714,19 @@ public function messageCount() {
    +    } catch (DatabaseException $e) {
    

    Coding standards - put catch on separate line.

Thanks!

ckaotik’s picture

Added the changes suggested by Mike, and an interdiff against #2. Now that only leaves tests :)

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mikeryan’s picture

Status: Needs work » Needs review

Last patch never went through testbot, let's see if it still applies.

Status: Needs review » Needs work

The last submitted patch, 9: delay_sql_map_init-2817833-9.patch, failed testing.

mikeryan’s picture

Issue tags: +Needs reroll
jofitz’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
4.85 KB

Re-rolled.

jofitz’s picture

Status: Needs review » Needs work

Setting back to NW for adding tests.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jofitz’s picture

Status: Needs work » Needs review
FileSize
4.82 KB

Re-rolled.

heddn’s picture

Status: Needs review » Needs work

Back to NW for tests.

jofitz’s picture

@heddn Can you provide any guidance on writing the tests for this? I had a look when I did the re-roll, but couldn't work it out.

heddn’s picture

I think we need to do a db table exists check when we don't want the table to exist. Then bootstrap things further and expect the table is now created.

jofitz’s picture

Added test.
(no interdiff because the only change is in the test_only patch)

The last submitted patch, 21: 2817833-21-test_only.patch, failed testing. View results

heddn’s picture

Status: Needs review » Needs work

I see what we are trying to do here. But I wonder if a better fix is to remove init() from getDatabase(). Classically, a getter shouldn't be doing anything but, well, getting.

jofitz’s picture

I totally agree, @heddn, but I'm not sure where the call to init() should go. Should it be not protected, perhaps?

quietone’s picture

Status: Needs work » Needs review

Yes, it would be nice to remove init() from getDatabase. However that was not introduced by the patch, and I suggest it is outside the scope of the issue. How about a new issue for removing init() from getDatabase and this can, probably, be RTBC?

Setting to NR for feedback.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

heddn’s picture

Status: Needs review » Needs work

Let's add the new issue to refactor init(). And then this is good to go.

jofitz’s picture

Status: Needs work » Reviewed & tested by the community
catch’s picture

Status: Reviewed & tested by the community » Fixed

I was expecting the patch here to do what the follow-up will, but I appreciate the performance improvement here as well, so let's keep going in the follow-up (also commented there).

Committed/pushed to 8.6.x and cherry-picked to 8.5.x. Thanks!

  • catch committed dc22273 on 8.6.x
    Issue #2817833 by Jo Fitzgerald, ckaotik, svendecabooter: Delay sql map...

  • catch committed 936b752 on 8.5.x
    Issue #2817833 by Jo Fitzgerald, ckaotik, svendecabooter: Delay sql map...
tacituseu’s picture

  • alexpott committed 62886de on 8.5.x
    Revert "Issue #2817833 by Jo Fitzgerald, ckaotik, svendecabooter: Delay...

  • alexpott committed 6f8bc7b on 8.6.x
    Revert "Issue #2817833 by Jo Fitzgerald, ckaotik, svendecabooter: Delay...
alexpott’s picture

Status: Fixed » Needs work

Yep I confirmed this broke HEAD.

jofitz’s picture

Status: Needs work » Needs review
FileSize
3.56 KB
9.27 KB

Sorry, I didn't realise it was only tested on 8.4.x when I set to RTBC.

A couple of alterations resolve the test failures:

  1. Use the same database connection for the insert statements in the tests.
  2. When looping through the map tables to get the highest ID, continue to the next table rather than breaking out of the loop. This avoids missing the page map table that does exist.
quietone’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

@Jo Fitzgerald, thanks for fixing this. I was about to do this last review before bed but I can't apply the patch to 8.5.x or 8.6.x. Sorry, needs a reroll.

aleevas’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
18.94 KB

I'm rerolled patch from #36
Please review

quietone’s picture

@aleevas, thanks for the patch, and one that passed tests.

I was wondering why the patch is nearly twice the size of the previous patch and I now see it. The patch contains a diff of itself. Can you remake the patch so that is does not include a diff of the patch? Thanks.

  1. diff --git a/core/2817833-36.patch b/core/2817833-36.patch
    

Oops.

jofitz’s picture

Remove the patch diff.

bhanuprakashnani’s picture

FileSize
10.92 KB

Attached interdiff for patches 38 and 40.

quietone’s picture

Status: Needs review » Needs work

@bhanuprakashnani, Welcome to Drupal! Thanks for making the interdiff.

+++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php
@@ -977,7 +982,7 @@ function (array $id) {
+        continue;

Is this change necessary? Won't break and continue do the same in this case? And reverted this change and MigrateDrupal6AuditIdsTest and MigrateSqlIdMapTest, the two of the three tests that have previously failed, passed tests.

chiranjeeb2410’s picture

@quietone, according to what you stated in the previous comment, the task now is to undo the changes made in MigrateDrupal6AuditIdsTest, MigrateSqlIdMapTest and changing 'continue' back to 'break' right?

quietone’s picture

@chiranjeeb2410, I'm only questioning the change from break to continue, not the test files. So, a patch that reverts that one line would be good. It would either confirm my local testing or prove me wrong.

chiranjeeb2410’s picture

@quietone,

Reverting 'continue' to 'break' as stated. Should do the trick.

chiranjeeb2410’s picture

Status: Needs work » Needs review
FileSize
561 bytes

Fresh patch uploaded with above mentioned changes.

Status: Needs review » Needs work

The last submitted patch, 46: 2817833-46.patch, failed testing. View results

jofitz’s picture

Version: 8.5.x-dev » 8.6.x-dev
Status: Needs work » Needs review
FileSize
617 bytes
9.42 KB

@quietone continue moves onto the next item in the loop, while break exits the loop completely without addressing the remaining items. I have added a comment to help clarify things.

quietone’s picture

Status: Needs review » Needs work

@Jo Fitzgerald, well that is what I thought until I doubled checked the php manual. And then I proceeded to not understand the words on the screen! Definitely a case where RTFM did not work, or rather it was me not working. ;-) Thank you for taking the time to add a comment.

I found one thing, the new test is missing a docblock. Sorry I didn't see it earlier.

+++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
@@ -1010,4 +1010,23 @@ private function getIdMapContents() {
+  public function testMapTableCreation() {

Missing doc block

chiranjeeb2410’s picture

Status: Needs work » Needs review
FileSize
9.46 KB
501 bytes

@quietone,

Added missing docblock. Go green.

jofitz’s picture

Status: Needs review » Needs work

@chiranjeeb2410 The docblock needs some content, not {@inheritdoc}, see the other test functions in the file for inspiration.

chiranjeeb2410’s picture

Status: Needs work » Needs review
FileSize
9.53 KB
574 bytes

@Jo Fitzgerald,

Uploaded fresh patch as per suggestion. Please review.

heddn’s picture

Status: Needs review » Needs work
+++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php
index 80c55ef..2a6e0ac 100644
--- a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php

+++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
@@ -1010,4 +1010,27 @@ private function getIdMapContents() {
+   * plugin.

Small nit, but I think I would prefer something like: "Tests the MapTableCreation method". Simple is sometimes better.

chiranjeeb2410’s picture

@heddn,

Changing it right away. Seems better.

heddn’s picture

Did we miss uploading a patch in #54?

chiranjeeb2410’s picture

Status: Needs work » Needs review
FileSize
9.48 KB
591 bytes

@heddn,

Done as suggested in #53. Please review.

heddn’s picture

Issue tags: +Novice

Super nit: I don't see the parenthesis after the method name in the rest of this test class Can we stay consistent and remove those?

chiranjeeb2410’s picture

@heddn,

Done as suggested. Please review.

Anonymous’s picture

Great job here! Special point on additional profit from:

+++ b/core/modules/migrate/src/Plugin/migrate/id_map/Sql.php
@@ -161,6 +162,18 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
+    if (!isset($this->database)) {
+      $this->database = \Drupal::database();
+    }

Can it help to reduce random fails with #2906317: Random fail due to problems with database?!


+++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
@@ -1011,7 +1011,7 @@ private function getIdMapContents() {
+   * Tests the MapTableCreation method.

Nit: frankly, this version still causes a slight misunderstanding (at least to me). Because we do not have a method/class MapTableCreation. If we call the "method" - the process of creation mapping table, then maybe we should not write it like class notation.

Moreover, the main idea of the test is to verify that the tables are not created (earlier than necessary). Therefore, I suggest using the text from IS:Proposed resolution with a more detailed description.

heddn’s picture

Status: Needs review » Needs work

Seems like NW for #59.

chiranjeeb2410’s picture

@vaplas, what needs to be finalised from #59 for fixing this issue as of now?

Anonymous’s picture

Status: Needs work » Needs review

I'm sorry if my comment made unclear here. I just wanted to thank for the work, and offer a more detailed comment on the test method testMapTableCreation(). I introduced my version with attached patch. If it suits you, then it's RTBC for me too.

heddn’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Novice

Sorry, I didn't notice the uploaded patch in #59. It looks fine to me. Thanks for your fine work.

chiranjeeb2410’s picture

@vaplas,

Change suits the requirements. RTBC for me too.

alexpott’s picture

Adding reviewer credit.

  • alexpott committed e96ab4e on 8.6.x
    Issue #2817833 by Jo Fitzgerald, chiranjeeb2410, ckaotik, vaplas,...
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed e96ab4e and pushed to 8.6.x. Thanks!

diff --git a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
index 0451dbc7d9..bc849916d7 100644
--- a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
+++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
@@ -1011,7 +1011,7 @@ private function getIdMapContents() {
   }
 
   /**
-   * Tests the delay creation of the "map" and "message" migrate tables.
+   * Tests the delayed creation of the "map" and "message" migrate tables.
    */
   public function testMapTableCreation() {
     $id_map = $this->getIdMap();

Very minor update to the docs on commit.

Discussed the crediting of @catch and myself with other committers. @gaborhojtsy said:

@alexpott I think we do, assuming catch reviewed it when he committed and you figured it needs backport, etc :) those are contributions :)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.