Problem/Motivation

The current dump to is limited to running in Drupal 8 but with some tweaks it can actually be expanded to dump any database including d6 and d7. This allows us to deprecate and replace the d6/d7 dump scripts with a much more robust script. It also opens up the ability for this to replace the migrate script as a standard tool for building test fixtures. Bonus, you can even use it to make a wordpress test fixture.

Proposed resolution

Remove use of module handler in dump tool(It only added documentation, not functional code).
Push database arguments into options so they can be supplied at the command line.
Add import script so we can manually test scripts as well.

Remaining tasks

Discus, review, decide if scope is reasonable?

User interface changes

This doesn't actually change the current scripts other then the database options trickling in as extra features in the current dump script.

API changes

I don't think these classes would be considered "API" so none? The dump command was extremely limited in what it could do so it would not have been terribly useful to extend or use outside of the existing script.

Data model changes

None.

Additional note:
https://github.com/neclimdul/drupal/pull/2 has a commit history that might give some context to the changes in the patch.

Original Report

This is purely for manual testing. I recently couldn't debug a particular problem in simpletest for various reasons and wanted to manually see what was happening when a update was running so I wrote this script to manually import any of the database fixtures created with the /core/script/database_dump* scripts. It seemed like it might be useful to other people so here it is.

Comments

neclimdul created an issue. See original summary.

neclimdul’s picture

Title: Add import database script to mirror dump database script » Improve and generalize database dump tools
Issue summary: View changes
StatusFileSize
new29.8 KB

So let me generalize this a bit. The current script is a bit wonky and has unneeded limitations that we can remove and make it really flexible.

https://github.com/neclimdul/drupal/pull/2 has a commit history that might give some context to the changes in the patch.

Status: Needs review » Needs work

The last submitted patch, 2: improved-db-script-2550291-2.patch, failed testing.

neclimdul’s picture

Leaving this nw because even with this fix, its going to fail because of #2553661: KernelTestBase fails to set up FileCache

neclimdul’s picture

StatusFileSize
new1.13 KB
neclimdul’s picture

StatusFileSize
new1.13 KB

i don't know why it keeps droping my patches...

neclimdul’s picture

StatusFileSize
new29.84 KB

my goodness... 2 interdiffs? I'm done for today.

neclimdul’s picture

Status: Needs work » Needs review
StatusFileSize
new29.9 KB
new844 bytes

reroll. lets see what testbot thinks.

phenaproxima’s picture

Status: Needs review » Needs work

Found some nits, but only one thing glaringly wrong. There needs to be a way to specify certain tables which only exist in D6 and D7 should be dumped schema-only. Maybe a --schema-only option?

  1. +++ b/core/lib/Drupal/Core/Command/DbCommandBase.php
    @@ -0,0 +1,64 @@
    + * Contains \Drupal\Core\Command\DbCommandBase
    

    Nit: Needs a period at the end.

  2. +++ b/core/lib/Drupal/Core/Command/DbCommandBase.php
    @@ -0,0 +1,64 @@
    +  protected function configure() {
    

    No doc comment.

  3. +++ b/core/lib/Drupal/Core/Command/DbCommandBase.php
    @@ -0,0 +1,64 @@
    +  protected function getDatabaseConnection(InputInterface $input) {
    +
    +    // Load connection from a url.
    

    Nit: There's an extra line here.

  4. +++ b/core/lib/Drupal/Core/Command/DbCommandBase.php
    @@ -0,0 +1,64 @@
    +      // ensure database connection isn't set.
    

    Nit: s/ensure/Ensure

  5. +++ b/core/lib/Drupal/Core/Command/DbCommandBase.php
    @@ -0,0 +1,64 @@
    +      if (Database::getConnectionInfo('db-tools')) {
    +        throw new \RuntimeException('Database "db-tools" is already defined. Can not define database provided.');
    +      }
    

    Why are we relying on a specific connection ID being defined? This at least needs a comment to explain.

  6. +++ b/core/lib/Drupal/Core/Command/DbDumpCommand.php
    @@ -280,21 +261,23 @@ protected function getTableCollation($table, &$definition) {
    +    $query = $connection->query("SELECT * FROM {" . $table . "} " . $order );
    

    Nit: There's an extra space before the closing parenthesis.

  7. +++ b/core/lib/Drupal/Core/Command/DbDumpCommand.php
    @@ -388,8 +377,6 @@ protected function getTemplate() {
      * installation of Drupal 8. It has the following modules installed:
    - *
    -{{MODULES}}
    

    If we're removing the list of modules, we shouldn't say "It has the following modules installed" :)

  8. +++ b/core/lib/Drupal/Core/Command/DbImportCommand.php
    @@ -0,0 +1,74 @@
    +  protected function execute(InputInterface $input, OutputInterface $output) {
    +
    +    $script = $input->getArgument('script');
    

    Nit: There's an extra line.

  9. +++ b/core/modules/system/tests/src/Kernel/Scripts/DbImportCommandTest.php
    @@ -0,0 +1,182 @@
    +  public function testDbImportCommand() {
    +
    +    /** @var \Drupal\Core\Database\Connection $connection */
    +    $connection = $this->container->get('database');
    

    Nit: Empty extra line.

  10. +++ b/core/modules/system/tests/src/Kernel/Scripts/DbImportCommandTest.php
    @@ -0,0 +1,182 @@
    +        ->tableExists($table), strtr('Table @table created by the database script.', ['@table' => $table]));
    

    strtr()? Why not sprintf()?

The last submitted patch, 8: improve_and_generalize-2550291-8.patch, failed testing.

The last submitted patch, 8: improve_and_generalize-2550291-8.patch, failed testing.

webchick’s picture

Priority: Normal » Major

This allows us to remove massive WTF-ery from Migrate, so escalating to major.

neclimdul’s picture

StatusFileSize
new30.12 KB
new3.82 KB

1) 2) 3) 4) 6) 8) 9) done.

5) yeah, the docs where in the docblock for the method and wrong. Fixed and moved to the relevant code.

7) Actually the whole template is wrong. References the hopefully deprecated file script and references Drupal 8 being in the file where the point of this is we could dump anything from Drupal 6 to Wordpress.

10) sprintf uses %s and strtr lets me do @table which is more clear? I don't know I think I copied it from somewhere...

Note: leaving NW because #2553661: KernelTestBase fails to set up FileCache still blocks the tests.

neclimdul’s picture

Status: Needs work » Needs review

Oh hey, forgot to send this to testbot.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

Pending DrupalCI's OK for SQLite and PostgreSQL, I approve. This beats the tar out of migrate-db.sh.

phenaproxima’s picture

Status: Reviewed & tested by the community » Needs work

Dammit! I have kick this back to NW because of something we still need. To quote myself in #9:

There needs to be a way to specify certain tables which only exist in D6 and D7 should be dumped schema-only.

This would give the tool parity with migrate-db.sh, and thus we'll be able to remove it quickly and painlessly :)

neclimdul’s picture

Status: Needs work » Needs review
StatusFileSize
new15.78 KB
new35.9 KB

Now with even more tests (and some bug fixes... test coverage is good)

Status: Needs review » Needs work

The last submitted patch, 17: improve_and_generalize-2550291-17.patch, failed testing.

neclimdul’s picture

Status: Needs work » Needs review
StatusFileSize
new36.47 KB
new2.1 KB

that regex_quote broke wildcards. another test.

neclimdul’s picture

Patch is actually working. Sqlite adds a '.' to the end of the prefix in the constructor so the test is failing to confirm that the prefix is the value supplied... because its different. :(

The last submitted patch, 17: improve_and_generalize-2550291-17.patch, failed testing.

neclimdul’s picture

StatusFileSize
new36.63 KB
new848 bytes

lets try this.

phenaproxima’s picture

Found a lot of nits, but nothing functionally wrong!

  1. +++ b/core/lib/Drupal/Core/Command/DbCommandBase.php
    @@ -0,0 +1,65 @@
    +        throw new \RuntimeException('Database "db-tools" is already defined. Can not define database provided.');
    

    s/Can not/Cannot. Fixable on commit.

  2. +++ b/core/lib/Drupal/Core/Command/DbDumpCommand.php
    @@ -56,80 +41,77 @@ class DbDumpCommand extends Command {
    +      if (empty($schema_only_patterns) || preg_replace($schema_only_patterns, '', $table)) {
    

    Why use preg_replace() here? What's wrong with preg_match()?

  3. +++ b/core/lib/Drupal/Core/Command/DbImportCommand.php
    @@ -0,0 +1,73 @@
    +  /**
    +   * Run the database script.
    +   *
    +   * @param \Drupal\Core\Database\Connection $connection
    +   *   ...
    +   * @param string $script
    +   *   The PHP script.
    +   * @return mixed
    +   */
    +  protected function runScript(Connection $connection, $script) {
    

    $connection needs a proper doc comment :)

    $script should be specify that it's the path to a dump file script, not a string of PHP code to be executed.

    Why @return mixed? As far as I can tell, this method returns nothing.

  4. +++ b/core/modules/system/tests/src/Kernel/Scripts/DbCommandBaseTest.php
    @@ -0,0 +1,137 @@
    +    $command = new DbCommandBaseTester();
    +    $command_tester = new CommandTester($command);
    

    This is repeated throughout the test, can it be a protected property created in setUp()?

  5. +++ b/core/modules/system/tests/src/Kernel/Scripts/DbDumpCommandTest.php
    @@ -0,0 +1,85 @@
    +      $this->markTestSkipped("Skipping test since the DbDumpCommand is currently only compatible with MySql");
    

    Nit: s/MySql/MySQL

  6. +++ b/core/modules/system/tests/src/Kernel/Scripts/DbDumpCommandTest.php
    @@ -0,0 +1,85 @@
    +    $output = $command_tester->getDisplay();
    +    $this->assertTrue(strpos($output, "createTable('router"), 'Table router found');
    +    $this->assertTrue(strpos($output, "insert('router"), 'Insert found');
    +    $this->assertTrue(strpos($output, "'name' => 'test"), 'Insert name field found');
    +    $this->assertTrue(strpos($output, "'path' => 'test"), 'Insert path field found');
    +    $this->assertTrue(strpos($output, "'pattern_outline' => 'test"), 'Insert pattern_outline');
    

    I can't tell what exactly this is testing. It would benefit enormously from an explanatory comment.

  7. +++ b/core/modules/system/tests/src/Kernel/Scripts/DbDumpCommandTest.php
    @@ -0,0 +1,85 @@
    +    $output = $command_tester->getDisplay();
    +    $this->assertTrue(strpos($output, "createTable('router"), 'Table router found');
    +    $this->assertFalse(strpos($output, "insert('router"), 'Insert found');
    +    $this->assertFalse(strpos($output, "'name' => 'test"), 'Insert name field found');
    +    $this->assertFalse(strpos($output, "'path' => 'test"), 'Insert path field found');
    +    $this->assertFalse(strpos($output, "'pattern_outline' => 'test"), 'Insert pattern_outline');
    +
    +    $command_tester->execute(['--schema-only' => 'route.*']);
    +    $output = $command_tester->getDisplay();
    +    $this->assertTrue(strpos($output, "createTable('router"), 'Table router found');
    +    $this->assertFalse(strpos($output, "insert('router"), 'Insert found');
    +    $this->assertFalse(strpos($output, "'name' => 'test"), 'Insert name field found');
    +    $this->assertFalse(strpos($output, "'path' => 'test"), 'Insert path field found');
    +    $this->assertFalse(strpos($output, "'pattern_outline' => 'test"), 'Insert pattern_outline');
    

    Same here.

neclimdul’s picture

StatusFileSize
new6.08 KB
new36.94 KB

1) Done
2) Because preg_replace lets you replace and array of values(all the schema only table matches), preg_match would require a loop.
3) Done
4) Well, both the command and tester are commonly used through out the test so i'm not sure that's useful and would just add a lot of text.
5) done
6) 7) done. also improved assert message a little.

neclimdul’s picture

Better assertion, thanks for calling that out in IRC phena.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

DrupalCI approves! This patch makes me starry-eyed and sets my heart a-flutter. Totally, unabashedly RTBC.

The last submitted patch, 22: improve_and_generalize-2550291-22.patch, failed testing.

The last submitted patch, 24: improve_and_generalize-2550291-24.patch, failed testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 25: improve_and_generalize-2550291-25.patch, failed testing.

Status: Needs work » Needs review
neclimdul’s picture

Status: Needs review » Reviewed & tested by the community

oh pifr... i'm going to miss you... sort of.

webchick’s picture

Component: simpletest.module » migration system
Status: Reviewed & tested by the community » Fixed

This looks really awesome. I'll admit I didn't do a line-by-line comparison with migrate-db.sh but there's not a lot to complain about in this patch.

My one concern with this patch is it doesn't also remove migrate-db.sh. Which means if that doesn't get done by Sunday/Monday, we're at risk of shipping RC1 / 8.0.0 with both scripts, which is pretty silly.

Adam explained that this is because the patch to remove migrate-db.sh also needs to re-generate all the dumps and that's going to be an 11,000 GB patch so best to do on its own. That makes sense, but if folks could try really hard to get this done over the next 24-48 hours, it would be very much appreciated.

Committed and pushed to 8.0.x. Thanks!

  • webchick committed b291588 on 8.0.x
    Issue #2550291 by neclimdul, phenaproxima: Improve and generalize...

Status: Fixed » Closed (fixed)

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