Skip to content

Commit 13fe3de

Browse files
committed
ACP2E-1882: Database restoration fails due a delimiter error
1 parent 83b7f30 commit 13fe3de

File tree

3 files changed

+42
-29
lines changed
  • app/code/Magento/Backup/Model/ResourceModel
  • dev/tests/integration/testsuite/Magento/Framework/Backup
  • lib/internal/Magento/Framework/Backup/Filesystem/Iterator

3 files changed

+42
-29
lines changed

app/code/Magento/Backup/Model/ResourceModel/Db.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ public function rollBackTransaction()
301301
*/
302302
public function runCommand($command)
303303
{
304-
$this->connection->query($command);
304+
$this->connection->multiQuery($command);
305305
return $this;
306306
}
307307
}

dev/tests/integration/testsuite/Magento/Framework/Backup/DbTest.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
namespace Magento\Framework\Backup;
88

99
use Magento\Backup\Helper\Data;
10+
use Magento\Backup\Model\ResourceModel\Db;
1011
use Magento\Framework\App\Filesystem\DirectoryList;
1112
use Magento\Framework\Filesystem;
1213
use Magento\Framework\Module\Setup;
1314
use Magento\TestFramework\Helper\Bootstrap;
14-
use PHPUnit\Framework\TestCase;
15+
use Magento\Framework\Backup\BackupInterface;
1516

1617
/**
1718
* Provide tests for \Magento\Framework\Backup\Db.
@@ -32,16 +33,17 @@ public static function setUpBeforeClass(): void
3233
}
3334

3435
/**
35-
* Test db backup includes triggers.
36+
* Test db backup and rollback including triggers.
3637
*
3738
* @magentoConfigFixture default/system/backup/functionality_enabled 1
3839
* @magentoDataFixture Magento/Framework/Backup/_files/trigger.php
3940
* @magentoDbIsolation disabled
4041
*/
41-
public function testBackupIncludesCustomTriggers()
42+
public function testBackupAndRollbackIncludesCustomTriggers()
4243
{
4344
$helper = Bootstrap::getObjectManager()->get(Data::class);
4445
$time = time();
46+
/** BackupInterface $backupManager */
4547
$backupManager = Bootstrap::getObjectManager()->get(Factory::class)->create(
4648
Factory::TYPE_DB
4749
)->setBackupExtension(
@@ -60,6 +62,12 @@ public function testBackupIncludesCustomTriggers()
6062
'/CREATE TRIGGER `?test_custom_trigger`? AFTER INSERT ON `?'. $tableName . '`? FOR EACH ROW/',
6163
$content
6264
);
65+
66+
// Test rollback
67+
$backupResourceModel = Bootstrap::getObjectManager()->get(Db::class);
68+
$backupManager->setResourceModel($backupResourceModel);
69+
$backupManager->rollback();
70+
6371
//Clean up.
6472
$write->delete('/backups/' . $time . '_db_testbackup.sql');
6573
}

lib/internal/Magento/Framework/Backup/Filesystem/Iterator/File.php

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ class File extends \SplFileObject
1919
*/
2020
protected $_currentStatement = '';
2121

22+
/**
23+
* Store current statement delimiter.
24+
*
25+
* @var string
26+
*/
27+
private string $statementDelimiter = ';';
28+
2229
/**
2330
* Return current sql statement
2431
*
@@ -41,15 +48,35 @@ public function next()
4148
$this->_currentStatement = '';
4249
while (!$this->eof()) {
4350
$line = $this->fgets();
44-
if (strlen(trim($line))) {
45-
$this->_currentStatement .= $line;
46-
if ($this->_isLineLastInCommand($line)) {
51+
$trimmedLine = trim($line);
52+
if (!empty($trimmedLine) && !$this->isDelimiterChanged($trimmedLine)) {
53+
$statementFinalLine = '/(?<statement>.*)' . preg_quote($this->statementDelimiter, '/') . '$/';
54+
if (preg_match($statementFinalLine, $trimmedLine, $matches)) {
55+
$this->_currentStatement .= $matches['statement'];
4756
break;
57+
} else {
58+
$this->_currentStatement .= $line;
4859
}
4960
}
5061
}
5162
}
5263

64+
/**
65+
* Check whether statement delimiter has been changed.
66+
*
67+
* @param string $line
68+
* @return bool
69+
*/
70+
private function isDelimiterChanged(string $line): bool
71+
{
72+
if (preg_match('/^delimiter\s+(?<delimiter>.+)$/i', $line, $matches)) {
73+
$this->statementDelimiter = $matches['delimiter'];
74+
return true;
75+
}
76+
77+
return false;
78+
}
79+
5380
/**
5481
* Return to first statement
5582
*
@@ -72,26 +99,4 @@ protected function _isComment($line)
7299
{
73100
return $line[0] == '#' || ($line && substr($line, 0, 2) == '--');
74101
}
75-
76-
/**
77-
* Check is line a last in sql command
78-
*
79-
* @param string $line
80-
* @return bool
81-
*/
82-
protected function _isLineLastInCommand($line)
83-
{
84-
$cleanLine = trim($line);
85-
$lineLength = strlen($cleanLine);
86-
87-
$returnResult = false;
88-
if ($lineLength > 0) {
89-
$lastSymbolIndex = $lineLength - 1;
90-
if ($cleanLine[$lastSymbolIndex] == ';') {
91-
$returnResult = true;
92-
}
93-
}
94-
95-
return $returnResult;
96-
}
97102
}

0 commit comments

Comments
 (0)