1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Data\Persistence\Sql\Oracle;
6:
7: use Atk4\Data\Persistence\Sql\Connection as BaseConnection;
8: use Doctrine\DBAL\Configuration;
9: use Doctrine\DBAL\Driver;
10: use Doctrine\DBAL\Driver\Connection as DriverConnection;
11: use Doctrine\DBAL\Driver\Middleware;
12: use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
13:
14: class Connection extends BaseConnection
15: {
16: protected string $expressionClass = Expression::class;
17: protected string $queryClass = Query::class;
18:
19: #[\Override]
20: protected static function createDbalConfiguration(): Configuration
21: {
22: $configuration = parent::createDbalConfiguration();
23:
24: // setup connection globalization to use standard datetime format incl. microseconds support
25: // and make comparison of character types case insensitive
26: // based on https://github.com/doctrine/dbal/blob/3.6.5/src/Driver/OCI8/Middleware/InitializeSession.php
27: $initializeSessionMiddleware = new class() implements Middleware {
28: #[\Override]
29: public function wrap(Driver $driver): Driver
30: {
31: return new class($driver) extends AbstractDriverMiddleware {
32: #[\Override]
33: public function connect(
34: #[\SensitiveParameter]
35: array $params
36: ): DriverConnection {
37: $connection = parent::connect($params);
38:
39: $dateFormat = 'YYYY-MM-DD';
40: $timeFormat = 'HH24:MI:SS.FF6';
41: $tzFormat = 'TZH:TZM';
42:
43: $vars = [];
44: foreach ([
45: 'NLS_DATE_FORMAT' => $dateFormat,
46: 'NLS_TIME_FORMAT' => $timeFormat,
47: 'NLS_TIMESTAMP_FORMAT' => $dateFormat . ' ' . $timeFormat,
48: 'NLS_TIME_TZ_FORMAT' => $timeFormat . ' ' . $tzFormat,
49: 'NLS_TIMESTAMP_TZ_FORMAT' => $dateFormat . ' ' . $timeFormat . ' ' . $tzFormat,
50: 'NLS_NUMERIC_CHARACTERS' => '.,',
51: 'NLS_COMP' => 'LINGUISTIC',
52: 'NLS_SORT' => 'BINARY_CI',
53: ] as $k => $v) {
54: $vars[] = $k . " = '" . $v . "'";
55: }
56:
57: $connection->exec('ALTER SESSION SET ' . implode(' ', $vars));
58:
59: return $connection;
60: }
61: };
62: }
63: };
64:
65: $configuration->setMiddlewares([...$configuration->getMiddlewares(), $initializeSessionMiddleware]);
66:
67: return $configuration;
68: }
69:
70: #[\Override]
71: public function lastInsertId(string $sequence = null): string
72: {
73: if ($sequence) {
74: return $this->dsql()->field($this->expr('{{}}.CURRVAL', [$sequence]))->getOne();
75: }
76:
77: return parent::lastInsertId($sequence);
78: }
79: }
80: