Skip to content

Commit

Permalink
All SqlitePdoDataLayer::execute* methods support multi statement quer…
Browse files Browse the repository at this point in the history
…ies.
  • Loading branch information
prwater committed Oct 23, 2019
1 parent 49f8933 commit ffe60b6
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 135 deletions.
120 changes: 64 additions & 56 deletions src/SqlitePdoDataLayer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

use SetBased\Abc\Helper\Cast;
use SetBased\Exception\FallenException;
use SetBased\Exception\LogicException;
use SetBased\Stratum\Middle\Exception\ResultException;
use SetBased\Stratum\SqlitePdo\Exception\SqlitePdoDataLayerException;

Expand Down Expand Up @@ -38,6 +37,7 @@ class SqlitePdoDataLayer
private $volatile;

//--------------------------------------------------------------------------------------------------------------------

/**
* Object constructor.
*
Expand Down Expand Up @@ -108,77 +108,75 @@ public function close()
}
}

//--------------------------------------------------------------------------------------------------------------------
/**
* Executes a query that does not select any rows.
*
* @param string $query The SQL statement.
*/
public function executeNone(string $query): void
{
$this->query($query);
}

//--------------------------------------------------------------------------------------------------------------------
/**
* Executes multiple queries.
*
* Note: The \PDO driver does not have a native function for executing multiple SQL statements. Statements are
* separated by a semicolon followed by a new line or EOF.
*
* Comments are allowed and may contain
*
* @param string $queries The SQL statements.
* @param string $queries The SQL statements.
* @param array|null $parameters The parameters (i.e. replace pairs) of the query.
*
* @return int The number of executes queries.
* @return string The last query.
*/
public function executeNoneMulti(string $queries): int
public function executeLeadingQueries(string $queries, ?array $parameters): string
{
$parts = preg_split('/(;)[ \t\f\h]*\R/', $queries.PHP_EOL, -1, PREG_SPLIT_OFFSET_CAPTURE);
$parts = preg_split('/;[ \t\f\h]*\R/', $queries.PHP_EOL, -1, PREG_SPLIT_OFFSET_CAPTURE);
$lineCount = 1;

$count = 0;
foreach ($parts as $part)
if (sizeof($parts)==1)
{
$query = $part[0];
$last = array_pop($parts);
}
else
{
$last = array_pop($parts);
// If part does not end with semicolon the part is a comment at the end of the file.
if (mb_substr($queries, $part[1] + mb_strlen($query), 1)==';')
if (substr($queries, $last[1] + strlen($last[0]), 1)!==';')
{
$statement = $this->db->query($query);
if ($statement===false)
{
preg_match('/^(\s*)/', $query, $parts);
$lineCount += substr_count($parts[1], PHP_EOL);

$message = sprintf("%s, at line %d.", ($this->db->errorInfo())[2], $lineCount);

throw new SqlitePdoDataLayerException($this->db->errorCode(), $message, null, trim($query));
}

$count++;
$last = array_pop($parts);
}
}

foreach ($parts as $part)
{
$query = $part[0];
$this->query($query, $parameters);
$lineCount += substr_count($query, PHP_EOL) + 1;
}

return $count;
return str_repeat(PHP_EOL, $lineCount).$last[0];
}

//--------------------------------------------------------------------------------------------------------------------
/**
* Executes a query that does not select any rows.
*
* @param string $query The SQL statement.
* @param array|null $parameters The parameters (i.e. replace pairs) of the query.
*/
public function executeNone(string $query, ?array $parameters = null): void
{
$last = $this->executeLeadingQueries($query, $parameters);
$this->query($last, $parameters);
}

//--------------------------------------------------------------------------------------------------------------------
/**
* Executes a query that returns 1 and only 1 row.
* Throws an exception if the query selects none, 2 or more rows.
*
* @param string $query The SQL statement.
* @param string $query The SQL statement.
* @param array|null $parameters The parameters (i.e. replace pairs) of the query.
*
* @return array The selected row.
*
* @since 1.0.0
* @api
*/
public function executeRow0(string $query): ?array
public function executeRow0(string $query, ?array $parameters = null): ?array
{
$rows = $this->executeRows($query);
$rows = $this->executeRows($query, $parameters);
$n = count($rows);

switch ($n)
Expand All @@ -199,16 +197,17 @@ public function executeRow0(string $query): ?array
* Executes a query that returns 1 and only 1 row.
* Throws an exception if the query selects none, 2 or more rows.
*
* @param string $query The SQL statement.
* @param string $query The SQL statement.
* @param array|null $parameters The parameters (i.e. replace pairs) of the query.
*
* @return array The selected row.
*
* @since 1.0.0
* @api
*/
public function executeRow1(string $query): array
public function executeRow1(string $query, ?array $parameters = null): array
{
$rows = $this->executeRows($query);
$rows = $this->executeRows($query, $parameters);
$n = count($rows);
if ($n!=1)
{
Expand All @@ -222,13 +221,15 @@ public function executeRow1(string $query): array
/**
* Executes a query that returns 0 or more rows.
*
* @param string $query The SQL statement.
* @param string $query The SQL statement.
* @param array|null $parameters The parameters (i.e. replace pairs) of the query.
*
* @return array[] The selected rows.
*/
public function executeRows(string $query): array
public function executeRows(string $query, ?array $parameters = null): array
{
$statement = $this->query($query);
$last = $this->executeLeadingQueries($query, $parameters);
$statement = $this->query($last, $parameters);

$types = [];
for ($i = 0; $i<$statement->columnCount(); $i++)
Expand Down Expand Up @@ -267,16 +268,17 @@ public function executeRows(string $query): array
* Executes a query that returns 0 or 1 row with one column.
* Throws an exception if the query selects 2 or more rows.
*
* @param string $query The SQL statement.
* @param string $query The SQL statement.
* @param array|null $parameters The parameters (i.e. replace pairs) of the query.
*
* @return mixed The selected value.
*
* @since 1.0.0
* @api
*/
public function executeSingleton0(string $query)
public function executeSingleton0(string $query, ?array $parameters = null)
{
$rows = $this->executeRows($query);
$rows = $this->executeRows($query, $parameters);
$n = count($rows);

switch ($n)
Expand All @@ -297,16 +299,17 @@ public function executeSingleton0(string $query)
* Executes a query that returns 1 and only 1 row with 1 column.
* Throws an exception if the query selects none, 2 or more rows.
*
* @param string $query The SQL statement.
* @param string $query The SQL statement.
* @param array|null $parameters The parameters (i.e. replace pairs) of the query.
*
* @return mixed The selected value.
*
* @since 1.0.0
* @api
*/
public function executeSingleton1(string $query)
public function executeSingleton1(string $query, ?array $parameters = null)
{
$rows = $this->executeRows($query);
$rows = $this->executeRows($query, $parameters);
$n = count($rows);
if ($n!=1)
{
Expand Down Expand Up @@ -532,7 +535,7 @@ private function initFile(string $db, ?string $script, bool $volatile): void

if (!$exists && $script!==null)
{
$this->executeNoneMulti(file_get_contents($script));
$this->executeNone(file_get_contents($script));
}
}

Expand All @@ -549,7 +552,7 @@ private function initMemory(?string $script): void

if ($script!==null)
{
$this->executeNoneMulti(file_get_contents($script));
$this->executeNone(file_get_contents($script));
}
}

Expand All @@ -558,15 +561,20 @@ private function initMemory(?string $script): void
* Executes a query.
*
* @param string $query The query.
* @param array|null $parameters The parameters (i.e. replace pairs) of the query.
*
* @return \PDOStatement
*/
private function query(string $query): \PDOStatement
private function query(string $query, ?array $parameters): \PDOStatement
{
$statement = $this->db->query($query);
$statement = $this->db->query(($parameters===null) ? $query : strtr($query, $parameters));
if ($statement===false)
{
throw new SqlitePdoDataLayerException($this->db->errorCode(), ($this->db->errorInfo())[2], $query);
preg_match('/^(\s*)/', $query, $parts);
$line = substr_count($parts[1], PHP_EOL);
$message = sprintf("%s, at line %d.", ($this->db->errorInfo())[2], $line);

throw new SqlitePdoDataLayerException($this->db->errorCode(), $message, $query);
}

return $statement;
Expand Down
9 changes: 8 additions & 1 deletion src/Wrapper/LastInsertIdWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,15 @@ protected function getReturnTypeDeclaration(): string
*/
protected function writeResultHandler(): void
{
$this->codeStore->append('$this->executeNone($query);');
$this->codeStore->append('');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('$this->executeNone($query, $replace);');
}
else
{
$this->codeStore->append('$this->executeNone($query);');
}
$this->codeStore->append('return $this->lastInsertId();');
}

Expand Down
9 changes: 8 additions & 1 deletion src/Wrapper/NoneWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ protected function getReturnTypeDeclaration(): string
protected function writeResultHandler(): void
{
$this->codeStore->append('');
$this->codeStore->append('$this->executeNone($query);');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('$this->executeNone($query, $replace);');
}
else
{
$this->codeStore->append('$this->executeNone($query);');
}
}

//--------------------------------------------------------------------------------------------------------------------
Expand Down
9 changes: 8 additions & 1 deletion src/Wrapper/Row0Wrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ protected function getReturnTypeDeclaration(): string
protected function writeResultHandler(): void
{
$this->codeStore->append('');
$this->codeStore->append('return $this->executeRow0($query);');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('return $this->executeRow0($query, $replace);');
}
else
{
$this->codeStore->append('return $this->executeRow0($query);');
}
}

//--------------------------------------------------------------------------------------------------------------------
Expand Down
9 changes: 8 additions & 1 deletion src/Wrapper/Row1Wrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ protected function getReturnTypeDeclaration(): string
protected function writeResultHandler(): void
{
$this->codeStore->append('');
$this->codeStore->append('return $this->executeRow1($query);');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('return $this->executeRow1($query, $replace);');
}
else
{
$this->codeStore->append('return $this->executeRow1($query);');
}
}

//--------------------------------------------------------------------------------------------------------------------
Expand Down
9 changes: 8 additions & 1 deletion src/Wrapper/RowsWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ protected function getReturnTypeDeclaration(): string
protected function writeResultHandler(): void
{
$this->codeStore->append('');
$this->codeStore->append('return $this->executeRows($query);');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('return $this->executeRows($query, $replace);');
}
else
{
$this->codeStore->append('return $this->executeRows($query);');
}
}

//--------------------------------------------------------------------------------------------------------------------
Expand Down
18 changes: 16 additions & 2 deletions src/Wrapper/Singleton0Wrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,25 @@ protected function writeResultHandler(): void
$this->codeStore->append('');
if ($this->routine['return']=='bool')
{
$this->codeStore->append('return !empty($this->executeSingleton0($query));');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('return !empty($this->executeSingleton0($query, $replace));');
}
else
{
$this->codeStore->append('return !empty($this->executeSingleton0($query));');
}
}
else
{
$this->codeStore->append('return $this->executeSingleton0($query);');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('return $this->executeSingleton0($query, $replace);');
}
else
{
$this->codeStore->append('return $this->executeSingleton0($query);');
}
}
}

Expand Down
18 changes: 16 additions & 2 deletions src/Wrapper/Singleton1Wrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,25 @@ protected function writeResultHandler(): void
$this->codeStore->append('');
if ($this->routine['return']=='bool')
{
$this->codeStore->append('return !empty($this->executeSingleton1($query));');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('return !empty($this->executeSingleton1($query, $replace));');
}
else
{
$this->codeStore->append('return !empty($this->executeSingleton1($query));');
}
}
else
{
$this->codeStore->append('return $this->executeSingleton1($query);');
if ($this->hasRoutineArgs())
{
$this->codeStore->append('return $this->executeSingleton1($query, $replace);');
}
else
{
$this->codeStore->append('return $this->executeSingleton1($query);');
}
}
}

Expand Down

0 comments on commit ffe60b6

Please sign in to comment.