Skip to content

Commit

Permalink
allow string|Fqn for savepoints and unify the sanitization
Browse files Browse the repository at this point in the history
  • Loading branch information
hrach committed Oct 15, 2023
1 parent 1e7fc26 commit 69adaff
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 44 deletions.
6 changes: 3 additions & 3 deletions src/Drivers/IDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,23 +136,23 @@ public function rollbackTransaction(): void;
* @throws DriverException
* @internal
*/
public function createSavepoint(string $name): void;
public function createSavepoint(string|Fqn $name): void;


/**
* Releases the savepoint.
* @throws DriverException
* @internal
*/
public function releaseSavepoint(string $name): void;
public function releaseSavepoint(string|Fqn $name): void;


/**
* Rollbacks the savepoint.
* @throws DriverException
* @internal
*/
public function rollbackSavepoint(string $name): void;
public function rollbackSavepoint(string|Fqn $name): void;


/**
Expand Down
32 changes: 20 additions & 12 deletions src/Drivers/Mysqli/MysqliDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function connect(array $params, ILogger $logger): void
throw $this->createException(
$this->connection->connect_error ?? $this->connection->error, // @phpstan-ignore-line
$this->connection->connect_errno,
'HY000'
'HY000',
);
}

Expand Down Expand Up @@ -148,7 +148,7 @@ public function query(string $query): Result
$this->connection->error,
$this->connection->errno,
$this->connection->sqlstate,
$query
$query,
);
}

Expand Down Expand Up @@ -250,27 +250,24 @@ public function rollbackTransaction(): void
}


public function createSavepoint(string $name): void
public function createSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$identifier = str_replace(['`', '.'], ['``', '`.`'], $name);
$this->loggedQuery("SAVEPOINT $identifier");
$this->loggedQuery('SAVEPOINT ' . $this->convertIdentifierToSql($name));
}


public function releaseSavepoint(string $name): void
public function releaseSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$identifier = str_replace(['`', '.'], ['``', '`.`'], $name);
$this->loggedQuery("RELEASE SAVEPOINT $identifier");
$this->loggedQuery('RELEASE SAVEPOINT ' . $this->convertIdentifierToSql($name));
}


public function rollbackSavepoint(string $name): void
public function rollbackSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$identifier = str_replace(['`', '.'], ['``', '`.`'], $name);
$this->loggedQuery("ROLLBACK TO SAVEPOINT $identifier");
$this->loggedQuery('ROLLBACK TO SAVEPOINT ' . $this->convertIdentifierToSql($name));
}


Expand All @@ -297,7 +294,7 @@ protected function setupSsl(array $params): void
$params['sslCert'] ?? '',
$params['sslCa'] ?? '',
$params['sslCapath'] ?? '',
$params['sslCipher'] ?? ''
$params['sslCipher'] ?? '',
);
}

Expand Down Expand Up @@ -346,6 +343,17 @@ public function convertStringToSql(string $value): string
}


protected function convertIdentifierToSql(string|Fqn $identifier): string
{
$escaped = match (true) {
$identifier instanceof Fqn => str_replace('`', '``', $identifier->schema) . '.'
. str_replace('`', '``', $identifier->name),
default => str_replace('`', '``', $identifier),
};
return '`' . $escaped . '`';
}


/**
* This method is based on Doctrine\DBAL project.
* @link www.doctrine-project.org
Expand Down
8 changes: 4 additions & 4 deletions src/Drivers/Pdo/PdoDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,23 +208,23 @@ public function rollbackTransaction(): void
}


public function createSavepoint(string $name): void
public function createSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$identifier = $this->convertIdentifierToSql($name);
$this->loggedQuery("SAVEPOINT $identifier");
}


public function releaseSavepoint(string $name): void
public function releaseSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$identifier = $this->convertIdentifierToSql($name);
$this->loggedQuery("RELEASE SAVEPOINT $identifier");
}


public function rollbackSavepoint(string $name): void
public function rollbackSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$identifier = $this->convertIdentifierToSql($name);
Expand All @@ -246,7 +246,7 @@ public function convertStringToSql(string $value): string
abstract protected function createResultAdapter(PDOStatement $statement): IResultAdapter;


abstract protected function convertIdentifierToSql(string $identifier): string;
abstract protected function convertIdentifierToSql(string|Fqn $identifier): string;


abstract protected function createException(
Expand Down
8 changes: 6 additions & 2 deletions src/Drivers/PdoMysql/PdoMysqlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,13 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter
}


protected function convertIdentifierToSql(string $identifier): string
protected function convertIdentifierToSql(string|Fqn $identifier): string
{
return str_replace(['`', '.'], ['``', '`.`'], $identifier);
return match (true) {
$identifier instanceof Fqn => str_replace('`', '``', $identifier->schema) . '.'
. str_replace('`', '``', $identifier->name),
default => str_replace('`', '``', $identifier),
};
}


Expand Down
11 changes: 8 additions & 3 deletions src/Drivers/PdoPgsql/PdoPgsqlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed
assert($this->connection !== null);

$sequenceName = match (true) {
$sequenceName instanceOf Fqn => $this->convertIdentifierToSql($sequenceName->schema) . '.' .
$sequenceName instanceof Fqn => $this->convertIdentifierToSql($sequenceName->schema) . '.' .
$this->convertIdentifierToSql($sequenceName->name),
default => $this->convertIdentifierToSql($sequenceName),
};
Expand Down Expand Up @@ -115,9 +115,14 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter
}


protected function convertIdentifierToSql(string $identifier): string
protected function convertIdentifierToSql(string|Fqn $identifier): string
{
return '"' . str_replace(['"', '.'], ['""', '"."'], $identifier) . '"';
$escaped = match (true) {
$identifier instanceof Fqn => str_replace('"', '""', $identifier->schema) . '.'
. str_replace('"', '""', $identifier->name),
default => str_replace('"', '""', $identifier),
};
return '"' . $escaped . '"';
}


Expand Down
15 changes: 10 additions & 5 deletions src/Drivers/PdoSqlsrv/PdoSqlsrvDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,21 +118,21 @@ public function setTransactionIsolationLevel(int $level): void
}


public function createSavepoint(string $name): void
public function createSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$this->loggedQuery('SAVE TRANSACTION ' . $this->convertIdentifierToSql($name));
}


public function releaseSavepoint(string $name): void
public function releaseSavepoint(string|Fqn $name): void
{
// transaction are released automatically
// http://stackoverflow.com/questions/3101312/sql-server-2008-no-release-savepoint-for-current-transaction
}


public function rollbackSavepoint(string $name): void
public function rollbackSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$this->loggedQuery('ROLLBACK TRANSACTION ' . $this->convertIdentifierToSql($name));
Expand All @@ -146,9 +146,14 @@ protected function createResultAdapter(PDOStatement $statement): IResultAdapter
}


protected function convertIdentifierToSql(string $identifier): string
protected function convertIdentifierToSql(string|Fqn $identifier): string
{
return '[' . str_replace([']', '.'], [']]', '].['], $identifier) . ']';
$escaped = match (true) {
$identifier instanceof Fqn => str_replace(']', ']]', $identifier->schema) . '.'
. str_replace(']', ']]', $identifier->name),
default => str_replace(']', ']]', $identifier),
};
return '[' . $escaped . ']';
}


Expand Down
20 changes: 10 additions & 10 deletions src/Drivers/Pgsql/PgsqlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,7 @@ public function getLastInsertedId(string|Fqn|null $sequenceName = null): mixed
$this->checkConnection();
assert($this->connection !== null);

$sequenceName = match (true) {
$sequenceName instanceOf Fqn => pg_escape_identifier($this->connection, $sequenceName->schema) . '.' .
pg_escape_identifier($this->connection, $sequenceName->name),
default => pg_escape_identifier($this->connection, $sequenceName),
};
$sequenceName = $this->convertIdentifierToSql($sequenceName);
$sql = 'SELECT CURRVAL(\'' . $sequenceName . '\')';
return $this->loggedQuery($sql)->fetchField();
}
Expand Down Expand Up @@ -268,23 +264,23 @@ public function rollbackTransaction(): void
}


public function createSavepoint(string $name): void
public function createSavepoint(string|Fqn $name): void
{
$this->checkConnection();
assert($this->connection !== null);
$this->loggedQuery('SAVEPOINT ' . $this->convertIdentifierToSql($name));
}


public function releaseSavepoint(string $name): void
public function releaseSavepoint(string|Fqn $name): void
{
$this->checkConnection();
assert($this->connection !== null);
$this->loggedQuery('RELEASE SAVEPOINT ' . $this->convertIdentifierToSql($name));
}


public function rollbackSavepoint(string $name): void
public function rollbackSavepoint(string|Fqn $name): void
{
$this->checkConnection();
assert($this->connection !== null);
Expand All @@ -304,11 +300,15 @@ public function convertStringToSql(string $value): string
}


protected function convertIdentifierToSql(string $identifier): string
protected function convertIdentifierToSql(string|Fqn $identifier): string
{
$this->checkConnection();
assert($this->connection !== null);
$escaped = pg_escape_identifier($this->connection, $identifier);
$escaped = match (true) {
$identifier instanceof Fqn => pg_escape_identifier($this->connection, $identifier->schema) . '.' .
pg_escape_identifier($this->connection, $identifier->name),
default => pg_escape_identifier($this->connection, $identifier),
};
if ($escaped === false) {
throw new InvalidStateException();
}
Expand Down
15 changes: 10 additions & 5 deletions src/Drivers/Sqlsrv/SqlsrvDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -293,21 +293,21 @@ public function rollbackTransaction(): void
}


public function createSavepoint(string $name): void
public function createSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$this->loggedQuery('SAVE TRANSACTION ' . $this->convertIdentifierToSql($name));
}


public function releaseSavepoint(string $name): void
public function releaseSavepoint(string|Fqn $name): void
{
// transaction are released automatically
// http://stackoverflow.com/questions/3101312/sql-server-2008-no-release-savepoint-for-current-transaction
}


public function rollbackSavepoint(string $name): void
public function rollbackSavepoint(string|Fqn $name): void
{
$this->checkConnection();
$this->loggedQuery('ROLLBACK TRANSACTION ' . $this->convertIdentifierToSql($name));
Expand All @@ -320,9 +320,14 @@ public function convertStringToSql(string $value): string
}


protected function convertIdentifierToSql(string $value): string
protected function convertIdentifierToSql(string|Fqn $identifier): string
{
return '[' . str_replace([']', '.'], [']]', '].['], $value) . ']';
$escaped = match (true) {
$identifier instanceof Fqn => str_replace(']', ']]', $identifier->schema) . '.'
. str_replace(']', ']]', $identifier->name),
default => str_replace(']', ']]', $identifier),
};
return '[' . $escaped . ']';
}


Expand Down

0 comments on commit 69adaff

Please sign in to comment.