diff --git a/etc/phing-grammar.rng b/etc/phing-grammar.rng
index a023957d51..3714ede900 100644
--- a/etc/phing-grammar.rng
+++ b/etc/phing-grammar.rng
@@ -4908,6 +4908,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -4958,6 +4968,11 @@
+
+
+
+
+
diff --git a/src/Phing/Task/System/Pdo/DefaultPDOQuerySplitter.php b/src/Phing/Task/System/Pdo/DefaultPDOQuerySplitter.php
index 9f584398e4..f44283f547 100644
--- a/src/Phing/Task/System/Pdo/DefaultPDOQuerySplitter.php
+++ b/src/Phing/Task/System/Pdo/DefaultPDOQuerySplitter.php
@@ -75,10 +75,16 @@ public function nextQuery(): ?string
while (($line = $this->sqlReader->readLine()) !== null) {
$delimiter = $this->parent->getDelimiter();
$project = $this->parent->getOwningTarget()->getProject();
- $line = $project->replaceProperties(trim($line));
+ if (!$this->keepformat) {
+ $line = trim($line);
+ }
+ if ($this->expandProperties) {
+ $line = $project->replaceProperties($line);
+ }
if (
- ($line != $delimiter)
+ !$this->keepformat
+ && ($line !== $delimiter)
&& (StringHelper::startsWith('//', $line)
|| StringHelper::startsWith('--', $line)
|| StringHelper::startsWith('#', $line))
@@ -88,7 +94,7 @@ public function nextQuery(): ?string
if (
strlen($line) > 4
- && 'REM ' === strtoupper(substr($line, 0, 4))
+ && stripos($line, 'REM ') === 0
) {
continue;
}
@@ -110,13 +116,13 @@ public function nextQuery(): ?string
// SQL defines "--" as a comment to EOL
// and in Oracle it may contain a hint
// so we cannot just remove it, instead we must end it
- if (false !== strpos((string) $line, '--')) {
+ if (!$this->keepformat && false !== strpos((string) $line, '--')) {
$sql .= "\n";
}
// DELIM_ROW doesn't need this (as far as i can tell)
- if (PDOSQLExecTask::DELIM_NORMAL == $this->delimiterType) {
- $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($delimiter) . ')#';
+ if (PDOSQLExecTask::DELIM_NORMAL === $this->delimiterType) {
+ $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($delimiter, null) . ')#';
$sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE);
$this->sqlBacklog = '';
@@ -133,13 +139,13 @@ public function nextQuery(): ?string
}
}
- if ($hasQuery || (PDOSQLExecTask::DELIM_ROW == $this->delimiterType && $line == $delimiter)) {
+ if ($hasQuery || (PDOSQLExecTask::DELIM_ROW === $this->delimiterType && $line === $delimiter)) {
// this assumes there is always a delimter on the end of the SQL statement.
return StringHelper::substring(
$sql,
0,
strlen($sql) - strlen($delimiter)
- - (PDOSQLExecTask::DELIM_ROW == $this->delimiterType ? 2 : 1)
+ - (PDOSQLExecTask::DELIM_ROW === $this->delimiterType ? 2 : 1)
);
}
}
diff --git a/src/Phing/Task/System/Pdo/DummyPDOQuerySplitter.php b/src/Phing/Task/System/Pdo/DummyPDOQuerySplitter.php
index 566cd25437..03fa3fb612 100644
--- a/src/Phing/Task/System/Pdo/DummyPDOQuerySplitter.php
+++ b/src/Phing/Task/System/Pdo/DummyPDOQuerySplitter.php
@@ -42,10 +42,16 @@ public function nextQuery(): ?string
while (($line = $this->sqlReader->readLine()) !== null) {
$delimiter = $this->parent->getDelimiter();
$project = $this->parent->getOwningTarget()->getProject();
- $line = $project->replaceProperties(trim($line));
+ if (!$this->keepformat) {
+ $line = trim($line);
+ }
+ if ($this->expandProperties) {
+ $line = $project->replaceProperties($line);
+ }
if (
- ($line != $delimiter)
+ !$this->keepformat
+ && ($line !== $delimiter)
&& (StringHelper::startsWith('//', $line)
|| StringHelper::startsWith('--', $line)
|| StringHelper::startsWith('#', $line))
@@ -55,8 +61,15 @@ public function nextQuery(): ?string
$sql .= ' ' . $line . "\n";
+ // SQL defines "--" as a comment to EOL
+ // and in Oracle it may contain a hint
+ // so we cannot just remove it, instead we must end it
+ if (!$this->keepformat && strpos($line, '--') !== false) {
+ $sql .= "\n";
+ }
+
/*
- * fix issue with PDO and wrong formated multistatements
+ * fix issue with PDO and wrong formatted multi statements
*
* @issue 1108
*/
diff --git a/src/Phing/Task/System/Pdo/PDOQuerySplitter.php b/src/Phing/Task/System/Pdo/PDOQuerySplitter.php
index 89a90c409b..f667a9a055 100644
--- a/src/Phing/Task/System/Pdo/PDOQuerySplitter.php
+++ b/src/Phing/Task/System/Pdo/PDOQuerySplitter.php
@@ -44,6 +44,9 @@ abstract class PDOQuerySplitter
*/
protected $sqlReader;
+ protected $keepformat = false;
+ protected $expandProperties = true;
+
/**
* Constructor, sets the parent task and reader with SQL source.
*/
@@ -53,6 +56,16 @@ public function __construct(PDOSQLExecTask $parent, Reader $reader)
$this->sqlReader = new BufferedReader($reader);
}
+ public function setKeepformat(bool $keepformat): void
+ {
+ $this->keepformat = $keepformat;
+ }
+
+ public function setExpandProperties(bool $expandProps): void
+ {
+ $this->expandProperties = $expandProps;
+ }
+
/**
* Returns next query from SQL source, null if no more queries left.
*
diff --git a/src/Phing/Task/System/Pdo/PDOSQLExecFormatterElement.php b/src/Phing/Task/System/Pdo/PDOSQLExecFormatterElement.php
index e592c27d72..e515326750 100644
--- a/src/Phing/Task/System/Pdo/PDOSQLExecFormatterElement.php
+++ b/src/Phing/Task/System/Pdo/PDOSQLExecFormatterElement.php
@@ -75,6 +75,13 @@ class PDOSQLExecFormatterElement
*/
private $showheaders = true;
+ /**
+ * Print trailer.
+ *
+ * @var bool
+ */
+ private $showtrailers = true;
+
/**
* Whether to format XML output.
*
@@ -173,6 +180,10 @@ public function prepare(Location $location): void
if ($this->formatter instanceof PlainPDOResultFormatter) {
// set any options that apply to the plain formatter
$this->formatter->setShowheaders($this->showheaders);
+ if ($this->showtrailers) {
+ $this->formatter->setStatementCounter($this->parentTask->getGoodSQL());
+ $this->formatter->setShowtrailers($this->showtrailers);
+ }
$this->formatter->setRowdelim($this->rowdelimiter);
$this->formatter->setColdelim($this->coldelimiter);
} elseif ($this->formatter instanceof XMLPDOResultFormatter) {
@@ -274,7 +285,7 @@ public function getOutfile(): ?File
*/
public function setAppend(bool $append): void
{
- $this->append = (bool) $append;
+ $this->append = $append;
}
/**
@@ -298,6 +309,11 @@ public function setShowheaders($showheaders): void
$this->showheaders = (bool) $showheaders;
}
+ public function setShowtrailers($showtrailers): void
+ {
+ $this->showtrailers = (bool) $showtrailers;
+ }
+
/**
* Sets the column delimiter.
*
diff --git a/src/Phing/Task/System/Pdo/PDOSQLExecTask.php b/src/Phing/Task/System/Pdo/PDOSQLExecTask.php
index c015f9e84c..234bc89d86 100644
--- a/src/Phing/Task/System/Pdo/PDOSQLExecTask.php
+++ b/src/Phing/Task/System/Pdo/PDOSQLExecTask.php
@@ -176,6 +176,16 @@ class PDOSQLExecTask extends PDOTask implements Condition
*/
private $statementCountProperty;
+ /**
+ * @var bool
+ */
+ private $keepformat = false;
+
+ /**
+ * @var bool
+ */
+ private $expandProperties = true;
+
/**
* Set the name of the SQL file to be run.
* Required unless statements are enclosed in the build file.
@@ -297,6 +307,11 @@ public function setFetchmode($mode): void
}
}
+ public function getGoodSQL()
+ {
+ return $this->goodSql;
+ }
+
/**
* Property to set to "true" if a statement throws an error.
*
@@ -317,6 +332,16 @@ public function setStatementCountProperty(string $statementCountProperty): void
$this->statementCountProperty = $statementCountProperty;
}
+ public function setKeepformat(bool $keepformat): void
+ {
+ $this->keepformat = $keepformat;
+ }
+
+ public function setExpandProperties(bool $expandProps): void
+ {
+ $this->expandProperties = $expandProps;
+ }
+
/**
* Load the sql file and then execute it.
*
@@ -462,6 +487,9 @@ public function runStatements(Reader $reader): void
$splitter = new DefaultPDOQuerySplitter($this, $reader, $this->delimiterType);
}
+ $splitter->setExpandProperties($this->expandProperties);
+ $splitter->setKeepformat($this->keepformat);
+
try {
while (null !== ($query = $splitter->nextQuery())) {
$this->log('SQL: ' . $query, Project::MSG_VERBOSE);
@@ -553,7 +581,7 @@ protected function execSQL($sql): void
$this->log('Failed to execute: ' . $sql, Project::MSG_ERR);
$this->setErrorProp();
if ('abort' !== $this->onError) {
- $this->log((string)$e, Project::MSG_ERR);
+ $this->log((string) $e, Project::MSG_ERR);
}
if ('continue' !== $this->onError) {
throw new BuildException('Failed to execute SQL', $e);
@@ -572,7 +600,11 @@ protected function getConfiguredFormatters(): array
{
$formatters = [];
foreach ($this->formatters as $fe) {
- $formatters[] = $fe->getFormatter();
+ $formatter = $fe->getFormatter();
+ if ($formatter instanceof PlainPDOResultFormatter) {
+ $formatter->setStatementCounter($this->goodSql);
+ }
+ $formatters[] = $formatter;
}
return $formatters;
@@ -665,7 +697,7 @@ private function setProperty(?string $name, string $value): void
*/
private function closeQuietly(): void
{
- if (!$this->isAutocommit() && null !== $this->conn && 'abort' === $this->onError) {
+ if (null !== $this->conn && 'abort' === $this->onError && !$this->isAutocommit()) {
try {
$this->conn->rollback();
} catch (PDOException $ex) {
diff --git a/src/Phing/Task/System/Pdo/PlainPDOResultFormatter.php b/src/Phing/Task/System/Pdo/PlainPDOResultFormatter.php
index 1253f73b52..dc0efba946 100644
--- a/src/Phing/Task/System/Pdo/PlainPDOResultFormatter.php
+++ b/src/Phing/Task/System/Pdo/PlainPDOResultFormatter.php
@@ -45,6 +45,7 @@ class PlainPDOResultFormatter extends PDOResultFormatter
* @var bool
*/
private $showheaders = true;
+ private $showtrailers = false;
/**
* Column delimiter.
@@ -61,6 +62,7 @@ class PlainPDOResultFormatter extends PDOResultFormatter
* @var string
*/
private $rowdelimiter = PHP_EOL;
+ private $statementcounter = 0;
/**
* Set the showheaders attribute.
@@ -72,6 +74,21 @@ public function setShowheaders($v)
$this->showheaders = StringHelper::booleanValue($v);
}
+ /**
+ * Set the showtrailers attribute.
+ *
+ * @param bool $v
+ */
+ public function setShowtrailers($v)
+ {
+ $this->showtrailers = StringHelper::booleanValue($v);
+ }
+
+ public function setStatementCounter($count)
+ {
+ $this->statementcounter = $count;
+ }
+
/**
* Sets the column delimiter.
*
@@ -101,6 +118,10 @@ public function processRow($row)
{
$line = '';
+ if ($this->showtrailers) {
+ $this->out->write('# ' . $this->statementcounter . ' statement(s) successful executed.' . PHP_EOL);
+ }
+
if (!$this->colsprinted && $this->showheaders) {
$first = true;
foreach ($row as $fieldName => $ignore) {
diff --git a/tests/Phing/Task/Optional/PDOTaskTest.php b/tests/Phing/Task/Optional/PDOTaskTest.php
index a524d96cc8..d8b8958bf9 100644
--- a/tests/Phing/Task/Optional/PDOTaskTest.php
+++ b/tests/Phing/Task/Optional/PDOTaskTest.php
@@ -79,4 +79,12 @@ public function testStatementCountProp(): void
$this->executeTarget(__FUNCTION__);
$this->assertPropertyEquals('statement.count', 2);
}
+
+ public function testOptionalAttributes(): void
+ {
+ $this->executeTarget(__FUNCTION__);
+ $this->assertFileExists('result.txt');
+ $this->assertStringContainsString('# 3 statement(s) successful executed.', file_get_contents('result.txt'));
+ @unlink('result.txt');
+ }
}
diff --git a/tests/etc/tasks/ext/pdo/test.xml b/tests/etc/tasks/ext/pdo/test.xml
index ee78b296cb..9ef4f079c6 100644
--- a/tests/etc/tasks/ext/pdo/test.xml
+++ b/tests/etc/tasks/ext/pdo/test.xml
@@ -67,4 +67,26 @@
)]]>
+
+
+ DROP TABLE IF EXISTS xxxxx
+
+
+
+
+
+