forked from doctrine/dbal
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
946 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd" | ||
colors="true" | ||
beStrictAboutOutputDuringTests="true" | ||
beStrictAboutTodoAnnotatedTests="true" | ||
failOnRisky="true" | ||
failOnWarning="true" | ||
convertDeprecationsToExceptions="true" | ||
> | ||
<php> | ||
<ini name="error_reporting" value="-1" /> | ||
|
||
<var name="db_driver" value="odbc_sqlsrv"/> | ||
<var name="db_host" value="127.0.0.1" /> | ||
<var name="db_user" value="sa" /> | ||
<var name="db_password" value="Doctrine2018" /> | ||
<var name="db_dbname" value="doctrine" /> | ||
|
||
<var name="db_driver_option_Charset" value="UTF-8"/> | ||
<var name="db_driver_option_Driver" value="ODBC Driver 17 for SQL Server"/> | ||
<var name="db_driver_option_Encrypt" value="no"/> | ||
</php> | ||
|
||
<testsuites> | ||
<testsuite name="Doctrine DBAL Test Suite"> | ||
<directory>../../../tests</directory> | ||
</testsuite> | ||
</testsuites> | ||
|
||
<coverage> | ||
<include> | ||
<directory suffix=".php">../../../src</directory> | ||
</include> | ||
</coverage> | ||
</phpunit> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Doctrine\DBAL\Driver\API\ODBC; | ||
|
||
use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface; | ||
use Doctrine\DBAL\Driver\Exception; | ||
use Doctrine\DBAL\Exception\ConnectionException; | ||
use Doctrine\DBAL\Exception\ConstraintViolationException; | ||
use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException; | ||
use Doctrine\DBAL\Exception\DriverException; | ||
use Doctrine\DBAL\Exception\SyntaxErrorException; | ||
use Doctrine\DBAL\Exception\TableExistsException; | ||
use Doctrine\DBAL\Exception\TableNotFoundException; | ||
use Doctrine\DBAL\Query; | ||
|
||
final class ExceptionConverter implements ExceptionConverterInterface | ||
{ | ||
public function convert(Exception $exception, ?Query $query): DriverException | ||
{ | ||
switch ($exception->getSQLState()) { | ||
case '23000': | ||
return new ConstraintViolationException($exception, $query); | ||
case '28000': | ||
case 'S1T00': | ||
return new ConnectionException($exception, $query); | ||
case '37000': | ||
return new SyntaxErrorException($exception, $query); | ||
case 'S0001': | ||
return new TableExistsException($exception, $query); | ||
case 'S0002': | ||
return new TableNotFoundException($exception, $query); | ||
case 'S0022': | ||
return new DatabaseObjectNotFoundException($exception, $query); | ||
} | ||
|
||
return new DriverException($exception, $query); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Doctrine\DBAL\Driver\ODBC; | ||
|
||
use Doctrine\DBAL\Driver\Connection as ConnectionInterface; | ||
use Doctrine\DBAL\Driver\ODBC\Exception\Error; | ||
use Doctrine\DBAL\ParameterType; | ||
use Doctrine\DBAL\SQL\Parser; | ||
use LogicException; | ||
|
||
use function odbc_autocommit; | ||
use function odbc_close; | ||
use function odbc_commit; | ||
use function odbc_exec; | ||
use function odbc_rollback; | ||
|
||
class Connection implements ConnectionInterface | ||
{ | ||
/** @var resource */ | ||
private $connection; | ||
|
||
private Parser $parser; | ||
|
||
/** @param resource $connection */ | ||
public function __construct($connection) | ||
{ | ||
$this->connection = $connection; | ||
$this->parser = new Parser(false); | ||
} | ||
|
||
public function __destruct() | ||
{ | ||
if (! isset($this->connection)) { | ||
return; | ||
} | ||
|
||
@odbc_rollback($this->connection); | ||
@odbc_close($this->connection); | ||
} | ||
|
||
public function prepare(string $sql): Statement | ||
{ | ||
$visitor = new ConvertParameters(); | ||
$this->parser->parse($sql, $visitor); | ||
|
||
return new Statement($this->connection, $visitor->getSQL(), $visitor->getParameterMap()); | ||
} | ||
|
||
public function query(string $sql): Result | ||
{ | ||
$result = @odbc_exec($this->connection, $sql); | ||
if ($result === false) { | ||
throw Error::new($this->connection); | ||
} | ||
|
||
return new Result($result); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* | ||
* @psalm-return never | ||
*/ | ||
public function quote($value, $type = ParameterType::STRING): string | ||
{ | ||
throw new LogicException('The ODBC driver does not support quoting values.'); | ||
} | ||
|
||
public function exec(string $sql): int | ||
{ | ||
return $this->query($sql)->rowCount(); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* | ||
* @psalm-return never | ||
*/ | ||
public function lastInsertId($name = null) | ||
{ | ||
throw new LogicException('The ODBC driver does not support retrieving the last inserted ID.'); | ||
} | ||
|
||
public function beginTransaction(): bool | ||
{ | ||
return (bool) odbc_autocommit($this->connection, false); | ||
} | ||
|
||
public function commit(): bool | ||
{ | ||
$result = odbc_commit($this->connection); | ||
odbc_autocommit($this->connection, true); | ||
|
||
return $result; | ||
} | ||
|
||
public function rollBack(): bool | ||
{ | ||
$result = odbc_rollback($this->connection); | ||
odbc_autocommit($this->connection, true); | ||
|
||
return $result; | ||
} | ||
|
||
/** @return resource */ | ||
public function getNativeConnection() | ||
{ | ||
return $this->connection; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Doctrine\DBAL\Driver\ODBC; | ||
|
||
use Doctrine\DBAL\SQL\Parser\Visitor; | ||
|
||
use function count; | ||
use function implode; | ||
|
||
final class ConvertParameters implements Visitor | ||
{ | ||
/** @var list<string> */ | ||
private array $buffer = []; | ||
|
||
/** @var array<array-key, int> */ | ||
private array $parameterMap = []; | ||
|
||
public function acceptPositionalParameter(string $sql): void | ||
{ | ||
$position = count($this->parameterMap) + 1; | ||
$this->parameterMap[$position] = $position; | ||
$this->buffer[] = '?'; | ||
} | ||
|
||
public function acceptNamedParameter(string $sql): void | ||
{ | ||
$position = count($this->parameterMap) + 1; | ||
$this->parameterMap[$sql] = $position; | ||
$this->buffer[] = '?'; | ||
} | ||
|
||
public function acceptOther(string $sql): void | ||
{ | ||
$this->buffer[] = $sql; | ||
} | ||
|
||
public function getSQL(): string | ||
{ | ||
return implode('', $this->buffer); | ||
} | ||
|
||
/** @return array<array-key, int> */ | ||
public function getParameterMap(): array | ||
{ | ||
return $this->parameterMap; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Doctrine\DBAL\Driver\ODBC; | ||
|
||
use Doctrine\DBAL\Connection as ConnectionInterface; | ||
use Doctrine\DBAL\Driver as DriverInterface; | ||
use Doctrine\DBAL\Driver\API\ODBC\ExceptionConverter; | ||
use Doctrine\DBAL\Driver\ODBC\Exception\ConnectionFailed; | ||
use Doctrine\DBAL\Platforms\AbstractPlatform; | ||
use Doctrine\DBAL\Schema\AbstractSchemaManager; | ||
use Doctrine\Deprecations\Deprecation; | ||
use LogicException; | ||
use RuntimeException; | ||
use SensitiveParameter; | ||
|
||
use function is_bool; | ||
use function odbc_connect; | ||
use function odbc_connection_string_quote; | ||
use function odbc_connection_string_should_quote; | ||
|
||
use const PHP_VERSION_ID; | ||
|
||
final class Driver implements DriverInterface | ||
{ | ||
/** {@inheritDoc} */ | ||
public function connect( | ||
#[SensitiveParameter] | ||
array $params | ||
): Connection { | ||
$connection = @odbc_connect( | ||
$this->assembleDsn($params['driverOptions'] ?? []), | ||
$params['user'] ?? '', | ||
$params['password'] ?? '', | ||
); | ||
|
||
if ($connection === false) { | ||
throw ConnectionFailed::new(); | ||
} | ||
|
||
return new Connection($connection); | ||
} | ||
|
||
public function getDatabasePlatform(): AbstractPlatform | ||
{ | ||
throw new LogicException('The ODBC driver does not support platform detection.'); | ||
} | ||
|
||
public function getSchemaManager(ConnectionInterface $conn, AbstractPlatform $platform): AbstractSchemaManager | ||
{ | ||
Deprecation::triggerIfCalledFromOutside( | ||
'doctrine/dbal', | ||
'https://github.com/doctrine/dbal/pull/5458', | ||
'%s() is deprecated. Use AbstractPlatform::createSchemaManager() instead.', | ||
__METHOD__, | ||
); | ||
|
||
return $platform->createSchemaManager($conn); | ||
} | ||
|
||
public function getExceptionConverter(): ExceptionConverter | ||
{ | ||
return new ExceptionConverter(); | ||
} | ||
|
||
/** @param array<string, mixed> $driverOptions */ | ||
private function assembleDsn(array $driverOptions): string | ||
{ | ||
$dsn = ''; | ||
foreach ($driverOptions as $key => $value) { | ||
$dsn .= $key . '=' . $this->quoteForDsn($value) . ';'; | ||
} | ||
|
||
return $dsn; | ||
} | ||
|
||
/** @param mixed $value */ | ||
private function quoteForDsn($value): string | ||
{ | ||
if (is_bool($value)) { | ||
$value = $value ? 'true' : 'false'; | ||
} else { | ||
$value = (string) $value; | ||
} | ||
|
||
if (PHP_VERSION_ID >= 80200) { | ||
return odbc_connection_string_should_quote($value) | ||
? odbc_connection_string_quote($value) | ||
: $value; | ||
} | ||
|
||
throw new RuntimeException('TODO'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Doctrine\DBAL\Driver\ODBC\Exception; | ||
|
||
use Doctrine\DBAL\Driver\AbstractException; | ||
|
||
use function odbc_error; | ||
use function odbc_errormsg; | ||
|
||
/** @psalm-immutable */ | ||
final class ConnectionFailed extends AbstractException | ||
{ | ||
public static function new(): self | ||
{ | ||
return new self(odbc_errormsg(), odbc_error()); | ||
} | ||
} |
Oops, something went wrong.