summaryrefslogtreecommitdiff
path: root/vendor/doctrine/dbal/src/Driver
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/doctrine/dbal/src/Driver')
-rw-r--r--vendor/doctrine/dbal/src/Driver/API/ExceptionConverter.php25
-rw-r--r--vendor/doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php47
-rw-r--r--vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php94
-rw-r--r--vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php52
-rw-r--r--vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php82
-rw-r--r--vendor/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php49
-rw-r--r--vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php85
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractException.php36
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractMySQLDriver.php86
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractOracleDriver.php38
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractOracleDriver/EasyConnectString.php112
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver/Exception/PortWithoutHost.php20
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver/Middleware/EnableForeignKeys.php33
-rw-r--r--vendor/doctrine/dbal/src/Driver/Connection.php93
-rw-r--r--vendor/doctrine/dbal/src/Driver/Exception.php25
-rw-r--r--vendor/doctrine/dbal/src/Driver/Exception/IdentityColumnsNotSupported.php21
-rw-r--r--vendor/doctrine/dbal/src/Driver/Exception/NoIdentityValue.php21
-rw-r--r--vendor/doctrine/dbal/src/Driver/FetchUtils.php69
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Connection.php131
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/DataSourceName.php80
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Driver.php41
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCreateTemporaryFile.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php29
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php28
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php35
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/PrepareFailed.php25
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php34
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Result.php106
-rw-r--r--vendor/doctrine/dbal/src/Driver/IBMDB2/Statement.php156
-rw-r--r--vendor/doctrine/dbal/src/Driver/Middleware.php12
-rw-r--r--vendor/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php69
-rw-r--r--vendor/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php39
-rw-r--r--vendor/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php68
-rw-r--r--vendor/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php26
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Connection.php112
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Driver.php117
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php30
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php35
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Exception/FailedReadingStreamOffset.php22
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Exception/HostRequired.php20
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidCharset.php41
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidOption.php24
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Exception/NonStreamResourceUsedAsLargeObject.php24
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Exception/StatementError.php30
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Initializer.php14
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Charset.php32
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Options.php28
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Secure.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Result.php164
-rw-r--r--vendor/doctrine/dbal/src/Driver/Mysqli/Statement.php154
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Connection.php119
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/ConvertPositionalToNamedPlaceholders.php58
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Driver.php60
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php26
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Exception/Error.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php20
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Exception/NonTerminatedStringLiteral.php27
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Exception/UnknownParameterIndex.php24
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/ExecutionMode.php30
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php40
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Result.php128
-rw-r--r--vendor/doctrine/dbal/src/Driver/OCI8/Statement.php103
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/Connection.php133
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/Exception.php30
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php76
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/OCI/Driver.php61
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php113
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/Result.php110
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php29
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php108
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php46
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php55
-rw-r--r--vendor/doctrine/dbal/src/Driver/PDO/Statement.php80
-rw-r--r--vendor/doctrine/dbal/src/Driver/PgSQL/Connection.php129
-rw-r--r--vendor/doctrine/dbal/src/Driver/PgSQL/ConvertParameters.php49
-rw-r--r--vendor/doctrine/dbal/src/Driver/PgSQL/Driver.php88
-rw-r--r--vendor/doctrine/dbal/src/Driver/PgSQL/Exception.php31
-rw-r--r--vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnexpectedValue.php29
-rw-r--r--vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnknownParameter.php20
-rw-r--r--vendor/doctrine/dbal/src/Driver/PgSQL/Result.php240
-rw-r--r--vendor/doctrine/dbal/src/Driver/PgSQL/Statement.php91
-rw-r--r--vendor/doctrine/dbal/src/Driver/Result.php93
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLSrv/Connection.php108
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLSrv/Driver.php73
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLSrv/Exception/Error.php44
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLSrv/Result.php104
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLSrv/Statement.php140
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLite3/Connection.php109
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLite3/Driver.php48
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLite3/Exception.php20
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLite3/Result.php88
-rw-r--r--vendor/doctrine/dbal/src/Driver/SQLite3/Statement.php61
-rw-r--r--vendor/doctrine/dbal/src/Driver/Statement.php39
98 files changed, 6010 insertions, 0 deletions
diff --git a/vendor/doctrine/dbal/src/Driver/API/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/ExceptionConverter.php
new file mode 100644
index 0000000..a7bf271
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/API/ExceptionConverter.php
@@ -0,0 +1,25 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\API;
6
7use Doctrine\DBAL\Driver\Exception;
8use Doctrine\DBAL\Exception\DriverException;
9use Doctrine\DBAL\Query;
10
11interface ExceptionConverter
12{
13 /**
14 * Converts a given driver-level exception into a DBAL-level driver exception.
15 *
16 * Implementors should use the vendor-specific error code and SQLSTATE of the exception
17 * and instantiate the most appropriate specialized {@see DriverException} subclass.
18 *
19 * @param Exception $exception The driver exception to convert.
20 * @param Query|null $query The SQL query that triggered the exception, if any.
21 *
22 * @return DriverException An instance of {@see DriverException} or one of its subclasses.
23 */
24 public function convert(Exception $exception, ?Query $query): DriverException;
25}
diff --git a/vendor/doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php
new file mode 100644
index 0000000..bcd5554
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php
@@ -0,0 +1,47 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\API\IBMDB2;
6
7use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
8use Doctrine\DBAL\Driver\Exception;
9use Doctrine\DBAL\Exception\ConnectionException;
10use Doctrine\DBAL\Exception\DriverException;
11use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
12use Doctrine\DBAL\Exception\InvalidFieldNameException;
13use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
14use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
15use Doctrine\DBAL\Exception\SyntaxErrorException;
16use Doctrine\DBAL\Exception\TableExistsException;
17use Doctrine\DBAL\Exception\TableNotFoundException;
18use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
19use Doctrine\DBAL\Query;
20
21/**
22 * @internal
23 *
24 * @link https://www.ibm.com/docs/en/db2/11.5?topic=messages-sql
25 */
26final class ExceptionConverter implements ExceptionConverterInterface
27{
28 public function convert(Exception $exception, ?Query $query): DriverException
29 {
30 return match ($exception->getCode()) {
31 -104 => new SyntaxErrorException($exception, $query),
32 -203 => new NonUniqueFieldNameException($exception, $query),
33 -204 => new TableNotFoundException($exception, $query),
34 -206 => new InvalidFieldNameException($exception, $query),
35 -407 => new NotNullConstraintViolationException($exception, $query),
36 -530,
37 -531,
38 -532,
39 -20356 => new ForeignKeyConstraintViolationException($exception, $query),
40 -601 => new TableExistsException($exception, $query),
41 -803 => new UniqueConstraintViolationException($exception, $query),
42 -1336,
43 -30082 => new ConnectionException($exception, $query),
44 default => new DriverException($exception, $query),
45 };
46 }
47}
diff --git a/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
new file mode 100644
index 0000000..ad0f0e1
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
@@ -0,0 +1,94 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\API\MySQL;
6
7use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
8use Doctrine\DBAL\Driver\Exception;
9use Doctrine\DBAL\Exception\ConnectionException;
10use Doctrine\DBAL\Exception\ConnectionLost;
11use Doctrine\DBAL\Exception\DatabaseDoesNotExist;
12use Doctrine\DBAL\Exception\DeadlockException;
13use Doctrine\DBAL\Exception\DriverException;
14use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
15use Doctrine\DBAL\Exception\InvalidFieldNameException;
16use Doctrine\DBAL\Exception\LockWaitTimeoutException;
17use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
18use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
19use Doctrine\DBAL\Exception\SyntaxErrorException;
20use Doctrine\DBAL\Exception\TableExistsException;
21use Doctrine\DBAL\Exception\TableNotFoundException;
22use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
23use Doctrine\DBAL\Query;
24
25/** @internal */
26final class ExceptionConverter implements ExceptionConverterInterface
27{
28 /**
29 * @link https://dev.mysql.com/doc/mysql-errors/8.0/en/client-error-reference.html
30 * @link https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html
31 */
32 public function convert(Exception $exception, ?Query $query): DriverException
33 {
34 return match ($exception->getCode()) {
35 1008 => new DatabaseDoesNotExist($exception, $query),
36 1213 => new DeadlockException($exception, $query),
37 1205 => new LockWaitTimeoutException($exception, $query),
38 1050 => new TableExistsException($exception, $query),
39 1051,
40 1146 => new TableNotFoundException($exception, $query),
41 1216,
42 1217,
43 1451,
44 1452,
45 1701 => new ForeignKeyConstraintViolationException($exception, $query),
46 1062,
47 1557,
48 1569,
49 1586 => new UniqueConstraintViolationException($exception, $query),
50 1054,
51 1166,
52 1611 => new InvalidFieldNameException($exception, $query),
53 1052,
54 1060,
55 1110 => new NonUniqueFieldNameException($exception, $query),
56 1064,
57 1149,
58 1287,
59 1341,
60 1342,
61 1343,
62 1344,
63 1382,
64 1479,
65 1541,
66 1554,
67 1626 => new SyntaxErrorException($exception, $query),
68 1044,
69 1045,
70 1046,
71 1049,
72 1095,
73 1142,
74 1143,
75 1227,
76 1370,
77 1429,
78 2002,
79 2005,
80 2054 => new ConnectionException($exception, $query),
81 2006,
82 4031 => new ConnectionLost($exception, $query),
83 1048,
84 1121,
85 1138,
86 1171,
87 1252,
88 1263,
89 1364,
90 1566 => new NotNullConstraintViolationException($exception, $query),
91 default => new DriverException($exception, $query),
92 };
93 }
94}
diff --git a/vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php
new file mode 100644
index 0000000..1c0dc79
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php
@@ -0,0 +1,52 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\API\OCI;
6
7use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
8use Doctrine\DBAL\Driver\Exception;
9use Doctrine\DBAL\Exception\ConnectionException;
10use Doctrine\DBAL\Exception\DatabaseDoesNotExist;
11use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException;
12use Doctrine\DBAL\Exception\DriverException;
13use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
14use Doctrine\DBAL\Exception\InvalidFieldNameException;
15use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
16use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
17use Doctrine\DBAL\Exception\SyntaxErrorException;
18use Doctrine\DBAL\Exception\TableExistsException;
19use Doctrine\DBAL\Exception\TableNotFoundException;
20use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
21use Doctrine\DBAL\Query;
22
23/** @internal */
24final class ExceptionConverter implements ExceptionConverterInterface
25{
26 /** @link http://www.dba-oracle.com/t_error_code_list.htm */
27 public function convert(Exception $exception, ?Query $query): DriverException
28 {
29 return match ($exception->getCode()) {
30 1,
31 2299,
32 38911 => new UniqueConstraintViolationException($exception, $query),
33 904 => new InvalidFieldNameException($exception, $query),
34 918,
35 960 => new NonUniqueFieldNameException($exception, $query),
36 923 => new SyntaxErrorException($exception, $query),
37 942 => new TableNotFoundException($exception, $query),
38 955 => new TableExistsException($exception, $query),
39 1017,
40 12545 => new ConnectionException($exception, $query),
41 1400 => new NotNullConstraintViolationException($exception, $query),
42 1918 => new DatabaseDoesNotExist($exception, $query),
43 2289,
44 2443,
45 4080 => new DatabaseObjectNotFoundException($exception, $query),
46 2266,
47 2291,
48 2292 => new ForeignKeyConstraintViolationException($exception, $query),
49 default => new DriverException($exception, $query),
50 };
51 }
52}
diff --git a/vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php
new file mode 100644
index 0000000..54e4966
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php
@@ -0,0 +1,82 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\API\PostgreSQL;
6
7use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
8use Doctrine\DBAL\Driver\Exception;
9use Doctrine\DBAL\Exception\ConnectionException;
10use Doctrine\DBAL\Exception\DatabaseDoesNotExist;
11use Doctrine\DBAL\Exception\DeadlockException;
12use Doctrine\DBAL\Exception\DriverException;
13use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
14use Doctrine\DBAL\Exception\InvalidFieldNameException;
15use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
16use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
17use Doctrine\DBAL\Exception\SchemaDoesNotExist;
18use Doctrine\DBAL\Exception\SyntaxErrorException;
19use Doctrine\DBAL\Exception\TableExistsException;
20use Doctrine\DBAL\Exception\TableNotFoundException;
21use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
22use Doctrine\DBAL\Query;
23
24use function str_contains;
25
26/** @internal */
27final class ExceptionConverter implements ExceptionConverterInterface
28{
29 /** @link http://www.postgresql.org/docs/9.4/static/errcodes-appendix.html */
30 public function convert(Exception $exception, ?Query $query): DriverException
31 {
32 switch ($exception->getSQLState()) {
33 case '40001':
34 case '40P01':
35 return new DeadlockException($exception, $query);
36
37 case '0A000':
38 // Foreign key constraint violations during a TRUNCATE operation
39 // are considered "feature not supported" in PostgreSQL.
40 if (str_contains($exception->getMessage(), 'truncate')) {
41 return new ForeignKeyConstraintViolationException($exception, $query);
42 }
43
44 break;
45
46 case '23502':
47 return new NotNullConstraintViolationException($exception, $query);
48
49 case '23503':
50 return new ForeignKeyConstraintViolationException($exception, $query);
51
52 case '23505':
53 return new UniqueConstraintViolationException($exception, $query);
54
55 case '3D000':
56 return new DatabaseDoesNotExist($exception, $query);
57
58 case '3F000':
59 return new SchemaDoesNotExist($exception, $query);
60
61 case '42601':
62 return new SyntaxErrorException($exception, $query);
63
64 case '42702':
65 return new NonUniqueFieldNameException($exception, $query);
66
67 case '42703':
68 return new InvalidFieldNameException($exception, $query);
69
70 case '42P01':
71 return new TableNotFoundException($exception, $query);
72
73 case '42P07':
74 return new TableExistsException($exception, $query);
75
76 case '08006':
77 return new ConnectionException($exception, $query);
78 }
79
80 return new DriverException($exception, $query);
81 }
82}
diff --git a/vendor/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php
new file mode 100644
index 0000000..561e58b
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php
@@ -0,0 +1,49 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\API\SQLSrv;
6
7use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
8use Doctrine\DBAL\Driver\Exception;
9use Doctrine\DBAL\Exception\ConnectionException;
10use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException;
11use Doctrine\DBAL\Exception\DriverException;
12use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
13use Doctrine\DBAL\Exception\InvalidFieldNameException;
14use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
15use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
16use Doctrine\DBAL\Exception\SyntaxErrorException;
17use Doctrine\DBAL\Exception\TableExistsException;
18use Doctrine\DBAL\Exception\TableNotFoundException;
19use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
20use Doctrine\DBAL\Query;
21
22/**
23 * @internal
24 *
25 * @link https://docs.microsoft.com/en-us/sql/relational-databases/errors-events/database-engine-events-and-errors
26 */
27final class ExceptionConverter implements ExceptionConverterInterface
28{
29 public function convert(Exception $exception, ?Query $query): DriverException
30 {
31 return match ($exception->getCode()) {
32 102 => new SyntaxErrorException($exception, $query),
33 207 => new InvalidFieldNameException($exception, $query),
34 208 => new TableNotFoundException($exception, $query),
35 209 => new NonUniqueFieldNameException($exception, $query),
36 515 => new NotNullConstraintViolationException($exception, $query),
37 547,
38 4712 => new ForeignKeyConstraintViolationException($exception, $query),
39 2601,
40 2627 => new UniqueConstraintViolationException($exception, $query),
41 2714 => new TableExistsException($exception, $query),
42 3701,
43 15151 => new DatabaseObjectNotFoundException($exception, $query),
44 11001,
45 18456 => new ConnectionException($exception, $query),
46 default => new DriverException($exception, $query),
47 };
48 }
49}
diff --git a/vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php
new file mode 100644
index 0000000..5885195
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php
@@ -0,0 +1,85 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\API\SQLite;
6
7use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
8use Doctrine\DBAL\Driver\Exception;
9use Doctrine\DBAL\Exception\ConnectionException;
10use Doctrine\DBAL\Exception\DriverException;
11use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
12use Doctrine\DBAL\Exception\InvalidFieldNameException;
13use Doctrine\DBAL\Exception\LockWaitTimeoutException;
14use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
15use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
16use Doctrine\DBAL\Exception\ReadOnlyException;
17use Doctrine\DBAL\Exception\SyntaxErrorException;
18use Doctrine\DBAL\Exception\TableExistsException;
19use Doctrine\DBAL\Exception\TableNotFoundException;
20use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
21use Doctrine\DBAL\Query;
22
23use function str_contains;
24
25/** @internal */
26final class ExceptionConverter implements ExceptionConverterInterface
27{
28 /** @link http://www.sqlite.org/c3ref/c_abort.html */
29 public function convert(Exception $exception, ?Query $query): DriverException
30 {
31 if (str_contains($exception->getMessage(), 'database is locked')) {
32 return new LockWaitTimeoutException($exception, $query);
33 }
34
35 if (
36 str_contains($exception->getMessage(), 'must be unique') ||
37 str_contains($exception->getMessage(), 'is not unique') ||
38 str_contains($exception->getMessage(), 'are not unique') ||
39 str_contains($exception->getMessage(), 'UNIQUE constraint failed')
40 ) {
41 return new UniqueConstraintViolationException($exception, $query);
42 }
43
44 if (
45 str_contains($exception->getMessage(), 'may not be NULL') ||
46 str_contains($exception->getMessage(), 'NOT NULL constraint failed')
47 ) {
48 return new NotNullConstraintViolationException($exception, $query);
49 }
50
51 if (str_contains($exception->getMessage(), 'no such table:')) {
52 return new TableNotFoundException($exception, $query);
53 }
54
55 if (str_contains($exception->getMessage(), 'already exists')) {
56 return new TableExistsException($exception, $query);
57 }
58
59 if (str_contains($exception->getMessage(), 'has no column named')) {
60 return new InvalidFieldNameException($exception, $query);
61 }
62
63 if (str_contains($exception->getMessage(), 'ambiguous column name')) {
64 return new NonUniqueFieldNameException($exception, $query);
65 }
66
67 if (str_contains($exception->getMessage(), 'syntax error')) {
68 return new SyntaxErrorException($exception, $query);
69 }
70
71 if (str_contains($exception->getMessage(), 'attempt to write a readonly database')) {
72 return new ReadOnlyException($exception, $query);
73 }
74
75 if (str_contains($exception->getMessage(), 'unable to open database file')) {
76 return new ConnectionException($exception, $query);
77 }
78
79 if (str_contains($exception->getMessage(), 'FOREIGN KEY constraint failed')) {
80 return new ForeignKeyConstraintViolationException($exception, $query);
81 }
82
83 return new DriverException($exception, $query);
84 }
85}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php b/vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php
new file mode 100644
index 0000000..9955a38
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
9use Doctrine\DBAL\Driver\API\IBMDB2\ExceptionConverter;
10use Doctrine\DBAL\Platforms\DB2Platform;
11use Doctrine\DBAL\ServerVersionProvider;
12
13/**
14 * Abstract base implementation of the {@see Driver} interface for IBM DB2 based drivers.
15 */
16abstract class AbstractDB2Driver implements Driver
17{
18 public function getDatabasePlatform(ServerVersionProvider $versionProvider): DB2Platform
19 {
20 return new DB2Platform();
21 }
22
23 public function getExceptionConverter(): ExceptionConverterInterface
24 {
25 return new ExceptionConverter();
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractException.php b/vendor/doctrine/dbal/src/Driver/AbstractException.php
new file mode 100644
index 0000000..367fc49
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractException.php
@@ -0,0 +1,36 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Exception as BaseException;
8use Throwable;
9
10/**
11 * Abstract base implementation of the {@see DriverException} interface.
12 *
13 * @psalm-immutable
14 */
15abstract class AbstractException extends BaseException implements Exception
16{
17 /**
18 * @param string $message The driver error message.
19 * @param string|null $sqlState The SQLSTATE the driver is in at the time the error occurred, if any.
20 * @param int $code The driver specific error code if any.
21 * @param Throwable|null $previous The previous throwable used for the exception chaining.
22 */
23 public function __construct(
24 string $message,
25 private readonly ?string $sqlState = null,
26 int $code = 0,
27 ?Throwable $previous = null,
28 ) {
29 parent::__construct($message, $code, $previous);
30 }
31
32 public function getSQLState(): ?string
33 {
34 return $this->sqlState;
35 }
36}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractMySQLDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractMySQLDriver.php
new file mode 100644
index 0000000..40d6507
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractMySQLDriver.php
@@ -0,0 +1,86 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
9use Doctrine\DBAL\Driver\API\MySQL\ExceptionConverter;
10use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
11use Doctrine\DBAL\Platforms\Exception\InvalidPlatformVersion;
12use Doctrine\DBAL\Platforms\MariaDB1052Platform;
13use Doctrine\DBAL\Platforms\MariaDB1060Platform;
14use Doctrine\DBAL\Platforms\MariaDBPlatform;
15use Doctrine\DBAL\Platforms\MySQL80Platform;
16use Doctrine\DBAL\Platforms\MySQLPlatform;
17use Doctrine\DBAL\ServerVersionProvider;
18
19use function preg_match;
20use function stripos;
21use function version_compare;
22
23/**
24 * Abstract base implementation of the {@see Driver} interface for MySQL based drivers.
25 */
26abstract class AbstractMySQLDriver implements Driver
27{
28 /**
29 * {@inheritDoc}
30 *
31 * @throws InvalidPlatformVersion
32 */
33 public function getDatabasePlatform(ServerVersionProvider $versionProvider): AbstractMySQLPlatform
34 {
35 $version = $versionProvider->getServerVersion();
36 if (stripos($version, 'mariadb') !== false) {
37 $mariaDbVersion = $this->getMariaDbMysqlVersionNumber($version);
38 if (version_compare($mariaDbVersion, '10.6.0', '>=')) {
39 return new MariaDB1060Platform();
40 }
41
42 if (version_compare($mariaDbVersion, '10.5.2', '>=')) {
43 return new MariaDB1052Platform();
44 }
45
46 return new MariaDBPlatform();
47 }
48
49 if (version_compare($version, '8.0.0', '>=')) {
50 return new MySQL80Platform();
51 }
52
53 return new MySQLPlatform();
54 }
55
56 public function getExceptionConverter(): ExceptionConverterInterface
57 {
58 return new ExceptionConverter();
59 }
60
61 /**
62 * Detect MariaDB server version, including hack for some mariadb distributions
63 * that starts with the prefix '5.5.5-'
64 *
65 * @param string $versionString Version string as returned by mariadb server, i.e. '5.5.5-Mariadb-10.0.8-xenial'
66 *
67 * @throws InvalidPlatformVersion
68 */
69 private function getMariaDbMysqlVersionNumber(string $versionString): string
70 {
71 if (
72 preg_match(
73 '/^(?:5\.5\.5-)?(mariadb-)?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)/i',
74 $versionString,
75 $versionParts,
76 ) === 0
77 ) {
78 throw InvalidPlatformVersion::new(
79 $versionString,
80 '^(?:5\.5\.5-)?(mariadb-)?<major_version>.<minor_version>.<patch_version>',
81 );
82 }
83
84 return $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch'];
85 }
86}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver.php
new file mode 100644
index 0000000..cf56cfa
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver.php
@@ -0,0 +1,38 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\AbstractOracleDriver\EasyConnectString;
9use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
10use Doctrine\DBAL\Driver\API\OCI\ExceptionConverter;
11use Doctrine\DBAL\Platforms\OraclePlatform;
12use Doctrine\DBAL\ServerVersionProvider;
13
14/**
15 * Abstract base implementation of the {@see Driver} interface for Oracle based drivers.
16 */
17abstract class AbstractOracleDriver implements Driver
18{
19 public function getDatabasePlatform(ServerVersionProvider $versionProvider): OraclePlatform
20 {
21 return new OraclePlatform();
22 }
23
24 public function getExceptionConverter(): ExceptionConverterInterface
25 {
26 return new ExceptionConverter();
27 }
28
29 /**
30 * Returns an appropriate Easy Connect String for the given parameters.
31 *
32 * @param array<string, mixed> $params The connection parameters to return the Easy Connect String for.
33 */
34 protected function getEasyConnectString(array $params): string
35 {
36 return (string) EasyConnectString::fromConnectionParameters($params);
37 }
38}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver/EasyConnectString.php b/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver/EasyConnectString.php
new file mode 100644
index 0000000..a777817
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver/EasyConnectString.php
@@ -0,0 +1,112 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\AbstractOracleDriver;
6
7use function implode;
8use function is_array;
9use function sprintf;
10
11/**
12 * Represents an Oracle Easy Connect string
13 *
14 * @link https://docs.oracle.com/database/121/NETAG/naming.htm
15 */
16final class EasyConnectString
17{
18 private function __construct(private readonly string $string)
19 {
20 }
21
22 public function __toString(): string
23 {
24 return $this->string;
25 }
26
27 /**
28 * Creates the object from an array representation
29 *
30 * @param mixed[] $params
31 */
32 public static function fromArray(array $params): self
33 {
34 return new self(self::renderParams($params));
35 }
36
37 /**
38 * Creates the object from the given DBAL connection parameters.
39 *
40 * @param mixed[] $params
41 */
42 public static function fromConnectionParameters(array $params): self
43 {
44 if (isset($params['connectstring'])) {
45 return new self($params['connectstring']);
46 }
47
48 if (! isset($params['host'])) {
49 return new self($params['dbname'] ?? '');
50 }
51
52 $connectData = [];
53
54 if (isset($params['servicename']) || isset($params['dbname'])) {
55 $serviceKey = 'SID';
56
57 if (isset($params['service'])) {
58 $serviceKey = 'SERVICE_NAME';
59 }
60
61 $serviceName = $params['servicename'] ?? $params['dbname'];
62
63 $connectData[$serviceKey] = $serviceName;
64 }
65
66 if (isset($params['instancename'])) {
67 $connectData['INSTANCE_NAME'] = $params['instancename'];
68 }
69
70 if (! empty($params['pooled'])) {
71 $connectData['SERVER'] = 'POOLED';
72 }
73
74 return self::fromArray([
75 'DESCRIPTION' => [
76 'ADDRESS' => [
77 'PROTOCOL' => 'TCP',
78 'HOST' => $params['host'],
79 'PORT' => $params['port'] ?? 1521,
80 ],
81 'CONNECT_DATA' => $connectData,
82 ],
83 ]);
84 }
85
86 /** @param mixed[] $params */
87 private static function renderParams(array $params): string
88 {
89 $chunks = [];
90
91 foreach ($params as $key => $value) {
92 $string = self::renderValue($value);
93
94 if ($string === '') {
95 continue;
96 }
97
98 $chunks[] = sprintf('(%s=%s)', $key, $string);
99 }
100
101 return implode('', $chunks);
102 }
103
104 private static function renderValue(mixed $value): string
105 {
106 if (is_array($value)) {
107 return self::renderParams($value);
108 }
109
110 return (string) $value;
111 }
112}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php
new file mode 100644
index 0000000..2efcddc
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
9use Doctrine\DBAL\Driver\API\PostgreSQL\ExceptionConverter;
10use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
11use Doctrine\DBAL\ServerVersionProvider;
12
13/**
14 * Abstract base implementation of the {@see Driver} interface for PostgreSQL based drivers.
15 */
16abstract class AbstractPostgreSQLDriver implements Driver
17{
18 public function getDatabasePlatform(ServerVersionProvider $versionProvider): PostgreSQLPlatform
19 {
20 return new PostgreSQLPlatform();
21 }
22
23 public function getExceptionConverter(): ExceptionConverterInterface
24 {
25 return new ExceptionConverter();
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php
new file mode 100644
index 0000000..8c2d012
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
9use Doctrine\DBAL\Driver\API\SQLSrv\ExceptionConverter;
10use Doctrine\DBAL\Platforms\SQLServerPlatform;
11use Doctrine\DBAL\ServerVersionProvider;
12
13/**
14 * Abstract base implementation of the {@see Driver} interface for Microsoft SQL Server based drivers.
15 */
16abstract class AbstractSQLServerDriver implements Driver
17{
18 public function getDatabasePlatform(ServerVersionProvider $versionProvider): SQLServerPlatform
19 {
20 return new SQLServerPlatform();
21 }
22
23 public function getExceptionConverter(): ExceptionConverterInterface
24 {
25 return new ExceptionConverter();
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver/Exception/PortWithoutHost.php b/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver/Exception/PortWithoutHost.php
new file mode 100644
index 0000000..ea8dcc4
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver/Exception/PortWithoutHost.php
@@ -0,0 +1,20 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9/**
10 * @internal
11 *
12 * @psalm-immutable
13 */
14final class PortWithoutHost extends AbstractException
15{
16 public static function new(): self
17 {
18 return new self('Connection port specified without the host');
19 }
20}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver.php
new file mode 100644
index 0000000..74a2b12
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
9use Doctrine\DBAL\Driver\API\SQLite\ExceptionConverter;
10use Doctrine\DBAL\Platforms\SQLitePlatform;
11use Doctrine\DBAL\ServerVersionProvider;
12
13/**
14 * Abstract base implementation of the {@see Driver} interface for SQLite based drivers.
15 */
16abstract class AbstractSQLiteDriver implements Driver
17{
18 public function getDatabasePlatform(ServerVersionProvider $versionProvider): SQLitePlatform
19 {
20 return new SQLitePlatform();
21 }
22
23 public function getExceptionConverter(): ExceptionConverterInterface
24 {
25 return new ExceptionConverter();
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver/Middleware/EnableForeignKeys.php b/vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver/Middleware/EnableForeignKeys.php
new file mode 100644
index 0000000..a7375cc
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver/Middleware/EnableForeignKeys.php
@@ -0,0 +1,33 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\AbstractSQLiteDriver\Middleware;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\Connection;
9use Doctrine\DBAL\Driver\Middleware;
10use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
11use SensitiveParameter;
12
13final class EnableForeignKeys implements Middleware
14{
15 public function wrap(Driver $driver): Driver
16 {
17 return new class ($driver) extends AbstractDriverMiddleware {
18 /**
19 * {@inheritDoc}
20 */
21 public function connect(
22 #[SensitiveParameter]
23 array $params,
24 ): Connection {
25 $connection = parent::connect($params);
26
27 $connection->exec('PRAGMA foreign_keys=ON');
28
29 return $connection;
30 }
31 };
32 }
33}
diff --git a/vendor/doctrine/dbal/src/Driver/Connection.php b/vendor/doctrine/dbal/src/Driver/Connection.php
new file mode 100644
index 0000000..68852e9
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Connection.php
@@ -0,0 +1,93 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\ServerVersionProvider;
8
9/**
10 * Connection interface.
11 * Driver connections must implement this interface.
12 */
13interface Connection extends ServerVersionProvider
14{
15 /**
16 * Prepares a statement for execution and returns a Statement object.
17 *
18 * @throws Exception
19 */
20 public function prepare(string $sql): Statement;
21
22 /**
23 * Executes an SQL statement, returning a result set as a Statement object.
24 *
25 * @throws Exception
26 */
27 public function query(string $sql): Result;
28
29 /**
30 * Quotes a string for use in a query.
31 *
32 * The usage of this method is discouraged. Use prepared statements
33 * or {@see AbstractPlatform::quoteStringLiteral()} instead.
34 */
35 public function quote(string $value): string;
36
37 /**
38 * Executes an SQL statement and return the number of affected rows.
39 * If the number of affected rows is greater than the maximum int value (PHP_INT_MAX),
40 * the number of affected rows may be returned as a string.
41 *
42 * @return int|numeric-string
43 *
44 * @throws Exception
45 */
46 public function exec(string $sql): int|string;
47
48 /**
49 * Returns the ID of the last inserted row.
50 *
51 * This method returns an integer or a string representing the value of the auto-increment column
52 * from the last row inserted into the database, if any, or throws an exception if a value cannot be returned,
53 * in particular when:
54 *
55 * - the driver does not support identity columns;
56 * - the last statement dit not return an identity (caution: see note below).
57 *
58 * Note: if the last statement was not an INSERT to an autoincrement column, this method MAY return an ID from a
59 * previous statement. DO NOT RELY ON THIS BEHAVIOR which is driver-dependent: always call this method right after
60 * executing an INSERT statement.
61 *
62 * @throws Exception
63 */
64 public function lastInsertId(): int|string;
65
66 /**
67 * Initiates a transaction.
68 *
69 * @throws Exception
70 */
71 public function beginTransaction(): void;
72
73 /**
74 * Commits a transaction.
75 *
76 * @throws Exception
77 */
78 public function commit(): void;
79
80 /**
81 * Rolls back the current transaction, as initiated by beginTransaction().
82 *
83 * @throws Exception
84 */
85 public function rollBack(): void;
86
87 /**
88 * Provides access to the native database connection.
89 *
90 * @return resource|object
91 */
92 public function getNativeConnection();
93}
diff --git a/vendor/doctrine/dbal/src/Driver/Exception.php b/vendor/doctrine/dbal/src/Driver/Exception.php
new file mode 100644
index 0000000..34d9a51
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Exception.php
@@ -0,0 +1,25 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Throwable;
8
9/**
10 * Contract for a driver exception.
11 *
12 * Driver exceptions provide the SQLSTATE of the driver
13 * and the driver specific error code at the time the error occurred.
14 *
15 * @psalm-immutable
16 */
17interface Exception extends Throwable
18{
19 /**
20 * Returns the SQLSTATE the driver was in at the time the error occurred.
21 *
22 * Returns null if the driver does not provide a SQLSTATE for the error occurred.
23 */
24 public function getSQLState(): ?string;
25}
diff --git a/vendor/doctrine/dbal/src/Driver/Exception/IdentityColumnsNotSupported.php b/vendor/doctrine/dbal/src/Driver/Exception/IdentityColumnsNotSupported.php
new file mode 100644
index 0000000..c904954
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Exception/IdentityColumnsNotSupported.php
@@ -0,0 +1,21 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8use Throwable;
9
10/**
11 * @internal
12 *
13 * @psalm-immutable
14 */
15final class IdentityColumnsNotSupported extends AbstractException
16{
17 public static function new(?Throwable $previous = null): self
18 {
19 return new self('The driver does not support identity columns.', null, 0, $previous);
20 }
21}
diff --git a/vendor/doctrine/dbal/src/Driver/Exception/NoIdentityValue.php b/vendor/doctrine/dbal/src/Driver/Exception/NoIdentityValue.php
new file mode 100644
index 0000000..decbbd5
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Exception/NoIdentityValue.php
@@ -0,0 +1,21 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8use Throwable;
9
10/**
11 * @internal
12 *
13 * @psalm-immutable
14 */
15final class NoIdentityValue extends AbstractException
16{
17 public static function new(?Throwable $previous = null): self
18 {
19 return new self('No identity value was generated by the last statement.', null, 0, $previous);
20 }
21}
diff --git a/vendor/doctrine/dbal/src/Driver/FetchUtils.php b/vendor/doctrine/dbal/src/Driver/FetchUtils.php
new file mode 100644
index 0000000..eda5211
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/FetchUtils.php
@@ -0,0 +1,69 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7/** @internal */
8final class FetchUtils
9{
10 /** @throws Exception */
11 public static function fetchOne(Result $result): mixed
12 {
13 $row = $result->fetchNumeric();
14
15 if ($row === false) {
16 return false;
17 }
18
19 return $row[0];
20 }
21
22 /**
23 * @return list<list<mixed>>
24 *
25 * @throws Exception
26 */
27 public static function fetchAllNumeric(Result $result): array
28 {
29 $rows = [];
30
31 while (($row = $result->fetchNumeric()) !== false) {
32 $rows[] = $row;
33 }
34
35 return $rows;
36 }
37
38 /**
39 * @return list<array<string,mixed>>
40 *
41 * @throws Exception
42 */
43 public static function fetchAllAssociative(Result $result): array
44 {
45 $rows = [];
46
47 while (($row = $result->fetchAssociative()) !== false) {
48 $rows[] = $row;
49 }
50
51 return $rows;
52 }
53
54 /**
55 * @return list<mixed>
56 *
57 * @throws Exception
58 */
59 public static function fetchFirstColumn(Result $result): array
60 {
61 $rows = [];
62
63 while (($row = $result->fetchOne()) !== false) {
64 $rows[] = $row;
65 }
66
67 return $rows;
68 }
69}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Connection.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Connection.php
new file mode 100644
index 0000000..2c8783b
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Connection.php
@@ -0,0 +1,131 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2;
6
7use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
8use Doctrine\DBAL\Driver\Exception\NoIdentityValue;
9use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionError;
10use Doctrine\DBAL\Driver\IBMDB2\Exception\PrepareFailed;
11use Doctrine\DBAL\Driver\IBMDB2\Exception\StatementError;
12use stdClass;
13
14use function assert;
15use function db2_autocommit;
16use function db2_commit;
17use function db2_escape_string;
18use function db2_exec;
19use function db2_last_insert_id;
20use function db2_num_rows;
21use function db2_prepare;
22use function db2_rollback;
23use function db2_server_info;
24use function error_get_last;
25
26use const DB2_AUTOCOMMIT_OFF;
27use const DB2_AUTOCOMMIT_ON;
28
29final class Connection implements ConnectionInterface
30{
31 /**
32 * @internal The connection can be only instantiated by its driver.
33 *
34 * @param resource $connection
35 */
36 public function __construct(private readonly mixed $connection)
37 {
38 }
39
40 public function getServerVersion(): string
41 {
42 $serverInfo = db2_server_info($this->connection);
43 assert($serverInfo instanceof stdClass);
44
45 return $serverInfo->DBMS_VER;
46 }
47
48 public function prepare(string $sql): Statement
49 {
50 $stmt = @db2_prepare($this->connection, $sql);
51
52 if ($stmt === false) {
53 throw PrepareFailed::new(error_get_last());
54 }
55
56 return new Statement($stmt);
57 }
58
59 public function query(string $sql): Result
60 {
61 return $this->prepare($sql)->execute();
62 }
63
64 public function quote(string $value): string
65 {
66 return "'" . db2_escape_string($value) . "'";
67 }
68
69 public function exec(string $sql): int|string
70 {
71 $stmt = @db2_exec($this->connection, $sql);
72
73 if ($stmt === false) {
74 throw StatementError::new();
75 }
76
77 $numRows = db2_num_rows($stmt);
78
79 if ($numRows === false) {
80 throw StatementError::new();
81 }
82
83 return $numRows;
84 }
85
86 public function lastInsertId(): string
87 {
88 $lastInsertId = db2_last_insert_id($this->connection);
89
90 if ($lastInsertId === null) {
91 throw NoIdentityValue::new();
92 }
93
94 return $lastInsertId;
95 }
96
97 public function beginTransaction(): void
98 {
99 if (db2_autocommit($this->connection, DB2_AUTOCOMMIT_OFF) !== true) {
100 throw ConnectionError::new($this->connection);
101 }
102 }
103
104 public function commit(): void
105 {
106 if (! db2_commit($this->connection)) {
107 throw ConnectionError::new($this->connection);
108 }
109
110 if (db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON) !== true) {
111 throw ConnectionError::new($this->connection);
112 }
113 }
114
115 public function rollBack(): void
116 {
117 if (! db2_rollback($this->connection)) {
118 throw ConnectionError::new($this->connection);
119 }
120
121 if (db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON) !== true) {
122 throw ConnectionError::new($this->connection);
123 }
124 }
125
126 /** @return resource */
127 public function getNativeConnection()
128 {
129 return $this->connection;
130 }
131}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/DataSourceName.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/DataSourceName.php
new file mode 100644
index 0000000..a1e5948
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/DataSourceName.php
@@ -0,0 +1,80 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2;
6
7use SensitiveParameter;
8
9use function implode;
10use function sprintf;
11use function str_contains;
12
13/**
14 * IBM DB2 DSN
15 */
16final class DataSourceName
17{
18 private function __construct(
19 #[SensitiveParameter]
20 private readonly string $string,
21 ) {
22 }
23
24 public function toString(): string
25 {
26 return $this->string;
27 }
28
29 /**
30 * Creates the object from an array representation
31 *
32 * @param array<string,mixed> $params
33 */
34 public static function fromArray(
35 #[SensitiveParameter]
36 array $params,
37 ): self {
38 $chunks = [];
39
40 foreach ($params as $key => $value) {
41 $chunks[] = sprintf('%s=%s', $key, $value);
42 }
43
44 return new self(implode(';', $chunks));
45 }
46
47 /**
48 * Creates the object from the given DBAL connection parameters.
49 *
50 * @param array<string,mixed> $params
51 */
52 public static function fromConnectionParameters(#[SensitiveParameter]
53 array $params,): self
54 {
55 if (isset($params['dbname']) && str_contains($params['dbname'], '=')) {
56 return new self($params['dbname']);
57 }
58
59 $dsnParams = [];
60
61 foreach (
62 [
63 'host' => 'HOSTNAME',
64 'port' => 'PORT',
65 'protocol' => 'PROTOCOL',
66 'dbname' => 'DATABASE',
67 'user' => 'UID',
68 'password' => 'PWD',
69 ] as $dbalParam => $dsnParam
70 ) {
71 if (! isset($params[$dbalParam])) {
72 continue;
73 }
74
75 $dsnParams[$dsnParam] = $params[$dbalParam];
76 }
77
78 return self::fromArray($dsnParams);
79 }
80}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Driver.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Driver.php
new file mode 100644
index 0000000..f2f4ed7
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Driver.php
@@ -0,0 +1,41 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2;
6
7use Doctrine\DBAL\Driver\AbstractDB2Driver;
8use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionFailed;
9use SensitiveParameter;
10
11use function db2_connect;
12use function db2_pconnect;
13
14final class Driver extends AbstractDB2Driver
15{
16 /**
17 * {@inheritDoc}
18 */
19 public function connect(
20 #[SensitiveParameter]
21 array $params,
22 ): Connection {
23 $dataSourceName = DataSourceName::fromConnectionParameters($params)->toString();
24
25 $username = $params['user'] ?? '';
26 $password = $params['password'] ?? '';
27 $driverOptions = $params['driverOptions'] ?? [];
28
29 if (! empty($params['persistent'])) {
30 $connection = db2_pconnect($dataSourceName, $username, $password, $driverOptions);
31 } else {
32 $connection = db2_connect($dataSourceName, $username, $password, $driverOptions);
33 }
34
35 if ($connection === false) {
36 throw ConnectionFailed::new();
37 }
38
39 return new Connection($connection);
40 }
41}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php
new file mode 100644
index 0000000..c584fb8
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9/**
10 * @internal
11 *
12 * @psalm-immutable
13 */
14final class CannotCopyStreamToStream extends AbstractException
15{
16 /** @psalm-param array{message: string, ...}|null $error */
17 public static function new(?array $error): self
18 {
19 $message = 'Could not copy source stream to temporary file';
20
21 if ($error !== null) {
22 $message .= ': ' . $error['message'];
23 }
24
25 return new self($message);
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCreateTemporaryFile.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCreateTemporaryFile.php
new file mode 100644
index 0000000..d7646a0
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCreateTemporaryFile.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9/**
10 * @internal
11 *
12 * @psalm-immutable
13 */
14final class CannotCreateTemporaryFile extends AbstractException
15{
16 /** @psalm-param array{message: string, ...}|null $error */
17 public static function new(?array $error): self
18 {
19 $message = 'Could not create temporary file';
20
21 if ($error !== null) {
22 $message .= ': ' . $error['message'];
23 }
24
25 return new self($message);
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php
new file mode 100644
index 0000000..b7bd8be
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php
@@ -0,0 +1,29 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function db2_conn_error;
10use function db2_conn_errormsg;
11
12/**
13 * @internal
14 *
15 * @psalm-immutable
16 */
17final class ConnectionError extends AbstractException
18{
19 /** @param resource $connection */
20 public static function new($connection): self
21 {
22 $message = db2_conn_errormsg($connection);
23 $sqlState = db2_conn_error($connection);
24
25 return Factory::create($message, static function (int $code) use ($message, $sqlState): self {
26 return new self($message, $sqlState, $code);
27 });
28 }
29}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php
new file mode 100644
index 0000000..9dd0443
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php
@@ -0,0 +1,28 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function db2_conn_error;
10use function db2_conn_errormsg;
11
12/**
13 * @internal
14 *
15 * @psalm-immutable
16 */
17final class ConnectionFailed extends AbstractException
18{
19 public static function new(): self
20 {
21 $message = db2_conn_errormsg();
22 $sqlState = db2_conn_error();
23
24 return Factory::create($message, static function (int $code) use ($message, $sqlState): self {
25 return new self($message, $sqlState, $code);
26 });
27 }
28}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php
new file mode 100644
index 0000000..91b9b43
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php
@@ -0,0 +1,35 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function preg_match;
10
11/**
12 * @internal
13 *
14 * @psalm-immutable
15 */
16final class Factory
17{
18 /**
19 * @param callable(int): T $constructor
20 *
21 * @return T
22 *
23 * @template T of AbstractException
24 */
25 public static function create(string $message, callable $constructor): AbstractException
26 {
27 $code = 0;
28
29 if (preg_match('/ SQL(\d+)N /', $message, $matches) === 1) {
30 $code = -(int) $matches[1];
31 }
32
33 return $constructor($code);
34 }
35}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/PrepareFailed.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/PrepareFailed.php
new file mode 100644
index 0000000..5344b65
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/PrepareFailed.php
@@ -0,0 +1,25 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9/**
10 * @internal
11 *
12 * @psalm-immutable
13 */
14final class PrepareFailed extends AbstractException
15{
16 /** @psalm-param array{message: string, ...}|null $error */
17 public static function new(?array $error): self
18 {
19 if ($error === null) {
20 return new self('Unknown error');
21 }
22
23 return new self($error['message']);
24 }
25}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php
new file mode 100644
index 0000000..6bf8511
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php
@@ -0,0 +1,34 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function db2_stmt_error;
10use function db2_stmt_errormsg;
11
12/**
13 * @internal
14 *
15 * @psalm-immutable
16 */
17final class StatementError extends AbstractException
18{
19 /** @param resource|null $statement */
20 public static function new($statement = null): self
21 {
22 if ($statement !== null) {
23 $message = db2_stmt_errormsg($statement);
24 $sqlState = db2_stmt_error($statement);
25 } else {
26 $message = db2_stmt_errormsg();
27 $sqlState = db2_stmt_error();
28 }
29
30 return Factory::create($message, static function (int $code) use ($message, $sqlState): self {
31 return new self($message, $sqlState, $code);
32 });
33 }
34}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Result.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Result.php
new file mode 100644
index 0000000..461f44a
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Result.php
@@ -0,0 +1,106 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2;
6
7use Doctrine\DBAL\Driver\FetchUtils;
8use Doctrine\DBAL\Driver\IBMDB2\Exception\StatementError;
9use Doctrine\DBAL\Driver\Result as ResultInterface;
10
11use function db2_fetch_array;
12use function db2_fetch_assoc;
13use function db2_free_result;
14use function db2_num_fields;
15use function db2_num_rows;
16use function db2_stmt_error;
17
18final class Result implements ResultInterface
19{
20 /**
21 * @internal The result can be only instantiated by its driver connection or statement.
22 *
23 * @param resource $statement
24 */
25 public function __construct(private readonly mixed $statement)
26 {
27 }
28
29 public function fetchNumeric(): array|false
30 {
31 $row = @db2_fetch_array($this->statement);
32
33 if ($row === false && db2_stmt_error($this->statement) !== '02000') {
34 throw StatementError::new($this->statement);
35 }
36
37 return $row;
38 }
39
40 public function fetchAssociative(): array|false
41 {
42 $row = @db2_fetch_assoc($this->statement);
43
44 if ($row === false && db2_stmt_error($this->statement) !== '02000') {
45 throw StatementError::new($this->statement);
46 }
47
48 return $row;
49 }
50
51 public function fetchOne(): mixed
52 {
53 return FetchUtils::fetchOne($this);
54 }
55
56 /**
57 * {@inheritDoc}
58 */
59 public function fetchAllNumeric(): array
60 {
61 return FetchUtils::fetchAllNumeric($this);
62 }
63
64 /**
65 * {@inheritDoc}
66 */
67 public function fetchAllAssociative(): array
68 {
69 return FetchUtils::fetchAllAssociative($this);
70 }
71
72 /**
73 * {@inheritDoc}
74 */
75 public function fetchFirstColumn(): array
76 {
77 return FetchUtils::fetchFirstColumn($this);
78 }
79
80 public function rowCount(): int
81 {
82 $numRows = @db2_num_rows($this->statement);
83
84 if ($numRows === false) {
85 throw StatementError::new($this->statement);
86 }
87
88 return $numRows;
89 }
90
91 public function columnCount(): int
92 {
93 $count = db2_num_fields($this->statement);
94
95 if ($count !== false) {
96 return $count;
97 }
98
99 return 0;
100 }
101
102 public function free(): void
103 {
104 db2_free_result($this->statement);
105 }
106}
diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Statement.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Statement.php
new file mode 100644
index 0000000..96852da
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Statement.php
@@ -0,0 +1,156 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\IBMDB2;
6
7use Doctrine\DBAL\Driver\Exception;
8use Doctrine\DBAL\Driver\IBMDB2\Exception\CannotCopyStreamToStream;
9use Doctrine\DBAL\Driver\IBMDB2\Exception\CannotCreateTemporaryFile;
10use Doctrine\DBAL\Driver\IBMDB2\Exception\StatementError;
11use Doctrine\DBAL\Driver\Statement as StatementInterface;
12use Doctrine\DBAL\ParameterType;
13
14use function assert;
15use function db2_bind_param;
16use function db2_execute;
17use function error_get_last;
18use function fclose;
19use function is_int;
20use function is_resource;
21use function stream_copy_to_stream;
22use function stream_get_meta_data;
23use function tmpfile;
24
25use const DB2_BINARY;
26use const DB2_CHAR;
27use const DB2_LONG;
28use const DB2_PARAM_FILE;
29use const DB2_PARAM_IN;
30
31final class Statement implements StatementInterface
32{
33 /** @var mixed[] */
34 private array $parameters = [];
35
36 /**
37 * Map of LOB parameter positions to the tuples containing reference to the variable bound to the driver statement
38 * and the temporary file handle bound to the underlying statement
39 *
40 * @var array<int,string|resource|null>
41 */
42 private array $lobs = [];
43
44 /**
45 * @internal The statement can be only instantiated by its driver connection.
46 *
47 * @param resource $stmt
48 */
49 public function __construct(private readonly mixed $stmt)
50 {
51 }
52
53 public function bindValue(int|string $param, mixed $value, ParameterType $type): void
54 {
55 assert(is_int($param));
56
57 switch ($type) {
58 case ParameterType::INTEGER:
59 $this->bind($param, $value, DB2_PARAM_IN, DB2_LONG);
60 break;
61
62 case ParameterType::LARGE_OBJECT:
63 $this->lobs[$param] = &$value;
64 break;
65
66 default:
67 $this->bind($param, $value, DB2_PARAM_IN, DB2_CHAR);
68 break;
69 }
70 }
71
72 /** @throws Exception */
73 private function bind(int $position, mixed &$variable, int $parameterType, int $dataType): void
74 {
75 $this->parameters[$position] =& $variable;
76
77 if (! db2_bind_param($this->stmt, $position, '', $parameterType, $dataType)) {
78 throw StatementError::new($this->stmt);
79 }
80 }
81
82 public function execute(): Result
83 {
84 $handles = $this->bindLobs();
85
86 $result = @db2_execute($this->stmt, $this->parameters);
87
88 foreach ($handles as $handle) {
89 fclose($handle);
90 }
91
92 $this->lobs = [];
93
94 if ($result === false) {
95 throw StatementError::new($this->stmt);
96 }
97
98 return new Result($this->stmt);
99 }
100
101 /**
102 * @return list<resource>
103 *
104 * @throws Exception
105 */
106 private function bindLobs(): array
107 {
108 $handles = [];
109
110 foreach ($this->lobs as $param => $value) {
111 if (is_resource($value)) {
112 $handle = $handles[] = $this->createTemporaryFile();
113 $path = stream_get_meta_data($handle)['uri'];
114
115 $this->copyStreamToStream($value, $handle);
116
117 $this->bind($param, $path, DB2_PARAM_FILE, DB2_BINARY);
118 } else {
119 $this->bind($param, $value, DB2_PARAM_IN, DB2_CHAR);
120 }
121
122 unset($value);
123 }
124
125 return $handles;
126 }
127
128 /**
129 * @return resource
130 *
131 * @throws Exception
132 */
133 private function createTemporaryFile()
134 {
135 $handle = @tmpfile();
136
137 if ($handle === false) {
138 throw CannotCreateTemporaryFile::new(error_get_last());
139 }
140
141 return $handle;
142 }
143
144 /**
145 * @param resource $source
146 * @param resource $target
147 *
148 * @throws Exception
149 */
150 private function copyStreamToStream($source, $target): void
151 {
152 if (@stream_copy_to_stream($source, $target) === false) {
153 throw CannotCopyStreamToStream::new(error_get_last());
154 }
155 }
156}
diff --git a/vendor/doctrine/dbal/src/Driver/Middleware.php b/vendor/doctrine/dbal/src/Driver/Middleware.php
new file mode 100644
index 0000000..4629d9a
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Middleware.php
@@ -0,0 +1,12 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\Driver;
8
9interface Middleware
10{
11 public function wrap(Driver $driver): Driver;
12}
diff --git a/vendor/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php
new file mode 100644
index 0000000..bdf9b2f
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php
@@ -0,0 +1,69 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Middleware;
6
7use Doctrine\DBAL\Driver\Connection;
8use Doctrine\DBAL\Driver\Result;
9use Doctrine\DBAL\Driver\Statement;
10
11abstract class AbstractConnectionMiddleware implements Connection
12{
13 public function __construct(private readonly Connection $wrappedConnection)
14 {
15 }
16
17 public function prepare(string $sql): Statement
18 {
19 return $this->wrappedConnection->prepare($sql);
20 }
21
22 public function query(string $sql): Result
23 {
24 return $this->wrappedConnection->query($sql);
25 }
26
27 public function quote(string $value): string
28 {
29 return $this->wrappedConnection->quote($value);
30 }
31
32 public function exec(string $sql): int|string
33 {
34 return $this->wrappedConnection->exec($sql);
35 }
36
37 public function lastInsertId(): int|string
38 {
39 return $this->wrappedConnection->lastInsertId();
40 }
41
42 public function beginTransaction(): void
43 {
44 $this->wrappedConnection->beginTransaction();
45 }
46
47 public function commit(): void
48 {
49 $this->wrappedConnection->commit();
50 }
51
52 public function rollBack(): void
53 {
54 $this->wrappedConnection->rollBack();
55 }
56
57 public function getServerVersion(): string
58 {
59 return $this->wrappedConnection->getServerVersion();
60 }
61
62 /**
63 * {@inheritDoc}
64 */
65 public function getNativeConnection()
66 {
67 return $this->wrappedConnection->getNativeConnection();
68 }
69}
diff --git a/vendor/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php
new file mode 100644
index 0000000..482f134
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php
@@ -0,0 +1,39 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Middleware;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\API\ExceptionConverter;
9use Doctrine\DBAL\Driver\Connection as DriverConnection;
10use Doctrine\DBAL\Platforms\AbstractPlatform;
11use Doctrine\DBAL\ServerVersionProvider;
12use SensitiveParameter;
13
14abstract class AbstractDriverMiddleware implements Driver
15{
16 public function __construct(private readonly Driver $wrappedDriver)
17 {
18 }
19
20 /**
21 * {@inheritDoc}
22 */
23 public function connect(
24 #[SensitiveParameter]
25 array $params,
26 ): DriverConnection {
27 return $this->wrappedDriver->connect($params);
28 }
29
30 public function getDatabasePlatform(ServerVersionProvider $versionProvider): AbstractPlatform
31 {
32 return $this->wrappedDriver->getDatabasePlatform($versionProvider);
33 }
34
35 public function getExceptionConverter(): ExceptionConverter
36 {
37 return $this->wrappedDriver->getExceptionConverter();
38 }
39}
diff --git a/vendor/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php
new file mode 100644
index 0000000..7da2f99
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php
@@ -0,0 +1,68 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Middleware;
6
7use Doctrine\DBAL\Driver\Result;
8
9abstract class AbstractResultMiddleware implements Result
10{
11 public function __construct(private readonly Result $wrappedResult)
12 {
13 }
14
15 public function fetchNumeric(): array|false
16 {
17 return $this->wrappedResult->fetchNumeric();
18 }
19
20 public function fetchAssociative(): array|false
21 {
22 return $this->wrappedResult->fetchAssociative();
23 }
24
25 public function fetchOne(): mixed
26 {
27 return $this->wrappedResult->fetchOne();
28 }
29
30 /**
31 * {@inheritDoc}
32 */
33 public function fetchAllNumeric(): array
34 {
35 return $this->wrappedResult->fetchAllNumeric();
36 }
37
38 /**
39 * {@inheritDoc}
40 */
41 public function fetchAllAssociative(): array
42 {
43 return $this->wrappedResult->fetchAllAssociative();
44 }
45
46 /**
47 * {@inheritDoc}
48 */
49 public function fetchFirstColumn(): array
50 {
51 return $this->wrappedResult->fetchFirstColumn();
52 }
53
54 public function rowCount(): int|string
55 {
56 return $this->wrappedResult->rowCount();
57 }
58
59 public function columnCount(): int
60 {
61 return $this->wrappedResult->columnCount();
62 }
63
64 public function free(): void
65 {
66 $this->wrappedResult->free();
67 }
68}
diff --git a/vendor/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php
new file mode 100644
index 0000000..6eaad50
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php
@@ -0,0 +1,26 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Middleware;
6
7use Doctrine\DBAL\Driver\Result;
8use Doctrine\DBAL\Driver\Statement;
9use Doctrine\DBAL\ParameterType;
10
11abstract class AbstractStatementMiddleware implements Statement
12{
13 public function __construct(private readonly Statement $wrappedStatement)
14 {
15 }
16
17 public function bindValue(int|string $param, mixed $value, ParameterType $type): void
18 {
19 $this->wrappedStatement->bindValue($param, $value, $type);
20 }
21
22 public function execute(): Result
23 {
24 return $this->wrappedStatement->execute();
25 }
26}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Connection.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Connection.php
new file mode 100644
index 0000000..cc00fb6
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Connection.php
@@ -0,0 +1,112 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli;
6
7use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
8use Doctrine\DBAL\Driver\Exception;
9use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
10use mysqli;
11use mysqli_sql_exception;
12
13final class Connection implements ConnectionInterface
14{
15 /**
16 * Name of the option to set connection flags
17 */
18 public const OPTION_FLAGS = 'flags';
19
20 /** @internal The connection can be only instantiated by its driver. */
21 public function __construct(private readonly mysqli $connection)
22 {
23 }
24
25 public function getServerVersion(): string
26 {
27 return $this->connection->get_server_info();
28 }
29
30 public function prepare(string $sql): Statement
31 {
32 try {
33 $stmt = $this->connection->prepare($sql);
34 } catch (mysqli_sql_exception $e) {
35 throw ConnectionError::upcast($e);
36 }
37
38 if ($stmt === false) {
39 throw ConnectionError::new($this->connection);
40 }
41
42 return new Statement($stmt);
43 }
44
45 public function query(string $sql): Result
46 {
47 return $this->prepare($sql)->execute();
48 }
49
50 public function quote(string $value): string
51 {
52 return "'" . $this->connection->escape_string($value) . "'";
53 }
54
55 public function exec(string $sql): int|string
56 {
57 try {
58 $result = $this->connection->query($sql);
59 } catch (mysqli_sql_exception $e) {
60 throw ConnectionError::upcast($e);
61 }
62
63 if ($result === false) {
64 throw ConnectionError::new($this->connection);
65 }
66
67 return $this->connection->affected_rows;
68 }
69
70 public function lastInsertId(): int|string
71 {
72 $lastInsertId = $this->connection->insert_id;
73
74 if ($lastInsertId === 0) {
75 throw Exception\NoIdentityValue::new();
76 }
77
78 return $this->connection->insert_id;
79 }
80
81 public function beginTransaction(): void
82 {
83 $this->connection->begin_transaction();
84 }
85
86 public function commit(): void
87 {
88 try {
89 if (! $this->connection->commit()) {
90 throw ConnectionError::new($this->connection);
91 }
92 } catch (mysqli_sql_exception $e) {
93 throw ConnectionError::upcast($e);
94 }
95 }
96
97 public function rollBack(): void
98 {
99 try {
100 if (! $this->connection->rollback()) {
101 throw ConnectionError::new($this->connection);
102 }
103 } catch (mysqli_sql_exception $e) {
104 throw ConnectionError::upcast($e);
105 }
106 }
107
108 public function getNativeConnection(): mysqli
109 {
110 return $this->connection;
111 }
112}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Driver.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Driver.php
new file mode 100644
index 0000000..9855e56
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Driver.php
@@ -0,0 +1,117 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli;
6
7use Doctrine\DBAL\Driver\AbstractMySQLDriver;
8use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionFailed;
9use Doctrine\DBAL\Driver\Mysqli\Exception\HostRequired;
10use Doctrine\DBAL\Driver\Mysqli\Initializer\Charset;
11use Doctrine\DBAL\Driver\Mysqli\Initializer\Options;
12use Doctrine\DBAL\Driver\Mysqli\Initializer\Secure;
13use Generator;
14use mysqli;
15use mysqli_sql_exception;
16use SensitiveParameter;
17
18final class Driver extends AbstractMySQLDriver
19{
20 /**
21 * {@inheritDoc}
22 */
23 public function connect(
24 #[SensitiveParameter]
25 array $params,
26 ): Connection {
27 if (! empty($params['persistent'])) {
28 if (! isset($params['host'])) {
29 throw HostRequired::forPersistentConnection();
30 }
31
32 $host = 'p:' . $params['host'];
33 } else {
34 $host = $params['host'] ?? '';
35 }
36
37 $connection = new mysqli();
38
39 foreach ($this->compilePreInitializers($params) as $initializer) {
40 $initializer->initialize($connection);
41 }
42
43 try {
44 $success = @$connection->real_connect(
45 $host,
46 $params['user'] ?? '',
47 $params['password'] ?? '',
48 $params['dbname'] ?? '',
49 $params['port'] ?? 0,
50 $params['unix_socket'] ?? '',
51 $params['driverOptions'][Connection::OPTION_FLAGS] ?? 0,
52 );
53 } catch (mysqli_sql_exception $e) {
54 throw ConnectionFailed::upcast($e);
55 }
56
57 if (! $success) {
58 throw ConnectionFailed::new($connection);
59 }
60
61 foreach ($this->compilePostInitializers($params) as $initializer) {
62 $initializer->initialize($connection);
63 }
64
65 return new Connection($connection);
66 }
67
68 /**
69 * @param array<string, mixed> $params
70 *
71 * @return Generator<int, Initializer>
72 */
73 private function compilePreInitializers(
74 #[SensitiveParameter]
75 array $params,
76 ): Generator {
77 unset($params['driverOptions'][Connection::OPTION_FLAGS]);
78
79 if (isset($params['driverOptions']) && $params['driverOptions'] !== []) {
80 yield new Options($params['driverOptions']);
81 }
82
83 if (
84 ! isset($params['ssl_key']) &&
85 ! isset($params['ssl_cert']) &&
86 ! isset($params['ssl_ca']) &&
87 ! isset($params['ssl_capath']) &&
88 ! isset($params['ssl_cipher'])
89 ) {
90 return;
91 }
92
93 yield new Secure(
94 $params['ssl_key'] ?? '',
95 $params['ssl_cert'] ?? '',
96 $params['ssl_ca'] ?? '',
97 $params['ssl_capath'] ?? '',
98 $params['ssl_cipher'] ?? '',
99 );
100 }
101
102 /**
103 * @param array<string, mixed> $params
104 *
105 * @return Generator<int, Initializer>
106 */
107 private function compilePostInitializers(
108 #[SensitiveParameter]
109 array $params,
110 ): Generator {
111 if (! isset($params['charset'])) {
112 return;
113 }
114
115 yield new Charset($params['charset']);
116 }
117}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php
new file mode 100644
index 0000000..d2477fd
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php
@@ -0,0 +1,30 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8use mysqli;
9use mysqli_sql_exception;
10use ReflectionProperty;
11
12/**
13 * @internal
14 *
15 * @psalm-immutable
16 */
17final class ConnectionError extends AbstractException
18{
19 public static function new(mysqli $connection): self
20 {
21 return new self($connection->error, $connection->sqlstate, $connection->errno);
22 }
23
24 public static function upcast(mysqli_sql_exception $exception): self
25 {
26 $p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
27
28 return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
29 }
30}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php
new file mode 100644
index 0000000..cb3bc64
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php
@@ -0,0 +1,35 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8use mysqli;
9use mysqli_sql_exception;
10use ReflectionProperty;
11
12use function assert;
13
14/**
15 * @internal
16 *
17 * @psalm-immutable
18 */
19final class ConnectionFailed extends AbstractException
20{
21 public static function new(mysqli $connection): self
22 {
23 $error = $connection->connect_error;
24 assert($error !== null);
25
26 return new self($error, 'HY000', $connection->connect_errno);
27 }
28
29 public static function upcast(mysqli_sql_exception $exception): self
30 {
31 $p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
32
33 return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
34 }
35}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/FailedReadingStreamOffset.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/FailedReadingStreamOffset.php
new file mode 100644
index 0000000..6f26dbe
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/FailedReadingStreamOffset.php
@@ -0,0 +1,22 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function sprintf;
10
11/**
12 * @internal
13 *
14 * @psalm-immutable
15 */
16final class FailedReadingStreamOffset extends AbstractException
17{
18 public static function new(int $parameter): self
19 {
20 return new self(sprintf('Failed reading the stream resource for parameter #%d.', $parameter));
21 }
22}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/HostRequired.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/HostRequired.php
new file mode 100644
index 0000000..d3359fc
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/HostRequired.php
@@ -0,0 +1,20 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9/**
10 * @internal
11 *
12 * @psalm-immutable
13 */
14final class HostRequired extends AbstractException
15{
16 public static function forPersistentConnection(): self
17 {
18 return new self('The "host" parameter is required for a persistent connection');
19 }
20}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidCharset.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidCharset.php
new file mode 100644
index 0000000..778ea64
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidCharset.php
@@ -0,0 +1,41 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8use mysqli;
9use mysqli_sql_exception;
10use ReflectionProperty;
11
12use function sprintf;
13
14/**
15 * @internal
16 *
17 * @psalm-immutable
18 */
19final class InvalidCharset extends AbstractException
20{
21 public static function fromCharset(mysqli $connection, string $charset): self
22 {
23 return new self(
24 sprintf('Failed to set charset "%s": %s', $charset, $connection->error),
25 $connection->sqlstate,
26 $connection->errno,
27 );
28 }
29
30 public static function upcast(mysqli_sql_exception $exception, string $charset): self
31 {
32 $p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
33
34 return new self(
35 sprintf('Failed to set charset "%s": %s', $charset, $exception->getMessage()),
36 $p->getValue($exception),
37 $exception->getCode(),
38 $exception,
39 );
40 }
41}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidOption.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidOption.php
new file mode 100644
index 0000000..654bb87
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidOption.php
@@ -0,0 +1,24 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function sprintf;
10
11/**
12 * @internal
13 *
14 * @psalm-immutable
15 */
16final class InvalidOption extends AbstractException
17{
18 public static function fromOption(int $option, mixed $value): self
19 {
20 return new self(
21 sprintf('Failed to set option %d with value "%s"', $option, $value),
22 );
23 }
24}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/NonStreamResourceUsedAsLargeObject.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/NonStreamResourceUsedAsLargeObject.php
new file mode 100644
index 0000000..566d636
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/NonStreamResourceUsedAsLargeObject.php
@@ -0,0 +1,24 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function sprintf;
10
11/**
12 * @internal
13 *
14 * @psalm-immutable
15 */
16final class NonStreamResourceUsedAsLargeObject extends AbstractException
17{
18 public static function new(int $parameter): self
19 {
20 return new self(
21 sprintf('The resource passed as a LARGE_OBJECT parameter #%d must be of type "stream"', $parameter),
22 );
23 }
24}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/StatementError.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/StatementError.php
new file mode 100644
index 0000000..991384c
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/StatementError.php
@@ -0,0 +1,30 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8use mysqli_sql_exception;
9use mysqli_stmt;
10use ReflectionProperty;
11
12/**
13 * @internal
14 *
15 * @psalm-immutable
16 */
17final class StatementError extends AbstractException
18{
19 public static function new(mysqli_stmt $statement): self
20 {
21 return new self($statement->error, $statement->sqlstate, $statement->errno);
22 }
23
24 public static function upcast(mysqli_sql_exception $exception): self
25 {
26 $p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
27
28 return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
29 }
30}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer.php
new file mode 100644
index 0000000..efab67e
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer.php
@@ -0,0 +1,14 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli;
6
7use Doctrine\DBAL\Driver\Exception;
8use mysqli;
9
10interface Initializer
11{
12 /** @throws Exception */
13 public function initialize(mysqli $connection): void;
14}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Charset.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Charset.php
new file mode 100644
index 0000000..d02c768
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Charset.php
@@ -0,0 +1,32 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Initializer;
6
7use Doctrine\DBAL\Driver\Mysqli\Exception\InvalidCharset;
8use Doctrine\DBAL\Driver\Mysqli\Initializer;
9use mysqli;
10use mysqli_sql_exception;
11
12final class Charset implements Initializer
13{
14 public function __construct(private readonly string $charset)
15 {
16 }
17
18 public function initialize(mysqli $connection): void
19 {
20 try {
21 $success = $connection->set_charset($this->charset);
22 } catch (mysqli_sql_exception $e) {
23 throw InvalidCharset::upcast($e, $this->charset);
24 }
25
26 if ($success) {
27 return;
28 }
29
30 throw InvalidCharset::fromCharset($connection, $this->charset);
31 }
32}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Options.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Options.php
new file mode 100644
index 0000000..3223951
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Options.php
@@ -0,0 +1,28 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Initializer;
6
7use Doctrine\DBAL\Driver\Mysqli\Exception\InvalidOption;
8use Doctrine\DBAL\Driver\Mysqli\Initializer;
9use mysqli;
10
11use function mysqli_options;
12
13final class Options implements Initializer
14{
15 /** @param array<int,mixed> $options */
16 public function __construct(private readonly array $options)
17 {
18 }
19
20 public function initialize(mysqli $connection): void
21 {
22 foreach ($this->options as $option => $value) {
23 if (! mysqli_options($connection, $option, $value)) {
24 throw InvalidOption::fromOption($option, $value);
25 }
26 }
27 }
28}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Secure.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Secure.php
new file mode 100644
index 0000000..fa819b5
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Secure.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli\Initializer;
6
7use Doctrine\DBAL\Driver\Mysqli\Initializer;
8use mysqli;
9use SensitiveParameter;
10
11final class Secure implements Initializer
12{
13 public function __construct(
14 #[SensitiveParameter]
15 private readonly string $key,
16 private readonly string $cert,
17 private readonly string $ca,
18 private readonly string $capath,
19 private readonly string $cipher,
20 ) {
21 }
22
23 public function initialize(mysqli $connection): void
24 {
25 $connection->ssl_set($this->key, $this->cert, $this->ca, $this->capath, $this->cipher);
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php
new file mode 100644
index 0000000..8d3c47a
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php
@@ -0,0 +1,164 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli;
6
7use Doctrine\DBAL\Driver\Exception;
8use Doctrine\DBAL\Driver\FetchUtils;
9use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
10use Doctrine\DBAL\Driver\Result as ResultInterface;
11use mysqli_sql_exception;
12use mysqli_stmt;
13
14use function array_column;
15use function array_combine;
16use function array_fill;
17use function count;
18
19final class Result implements ResultInterface
20{
21 /**
22 * Whether the statement result has columns. The property should be used only after the result metadata
23 * has been fetched ({@see $metadataFetched}). Otherwise, the property value is undetermined.
24 */
25 private readonly bool $hasColumns;
26
27 /**
28 * Mapping of statement result column indexes to their names. The property should be used only
29 * if the statement result has columns ({@see $hasColumns}). Otherwise, the property value is undetermined.
30 *
31 * @var array<int,string>
32 */
33 private readonly array $columnNames;
34
35 /** @var mixed[] */
36 private array $boundValues = [];
37
38 /**
39 * @internal The result can be only instantiated by its driver connection or statement.
40 *
41 * @throws Exception
42 */
43 public function __construct(private readonly mysqli_stmt $statement)
44 {
45 $meta = $statement->result_metadata();
46 $this->hasColumns = $meta !== false;
47 $this->columnNames = $meta !== false ? array_column($meta->fetch_fields(), 'name') : [];
48
49 if ($meta === false) {
50 return;
51 }
52
53 $meta->free();
54
55 // Store result of every execution which has it. Otherwise it will be impossible
56 // to execute a new statement in case if the previous one has non-fetched rows
57 // @link http://dev.mysql.com/doc/refman/5.7/en/commands-out-of-sync.html
58 $this->statement->store_result();
59
60 // Bind row values _after_ storing the result. Otherwise, if mysqli is compiled with libmysql,
61 // it will have to allocate as much memory as it may be needed for the given column type
62 // (e.g. for a LONGBLOB column it's 4 gigabytes)
63 // @link https://bugs.php.net/bug.php?id=51386#1270673122
64 //
65 // Make sure that the values are bound after each execution. Otherwise, if free() has been
66 // previously called on the result, the values are unbound making the statement unusable.
67 //
68 // It's also important that row values are bound after _each_ call to store_result(). Otherwise,
69 // if mysqli is compiled with libmysql, subsequently fetched string values will get truncated
70 // to the length of the ones fetched during the previous execution.
71 $this->boundValues = array_fill(0, count($this->columnNames), null);
72
73 // The following is necessary as PHP cannot handle references to properties properly
74 $refs = &$this->boundValues;
75
76 if (! $this->statement->bind_result(...$refs)) {
77 throw StatementError::new($this->statement);
78 }
79 }
80
81 public function fetchNumeric(): array|false
82 {
83 try {
84 $ret = $this->statement->fetch();
85 } catch (mysqli_sql_exception $e) {
86 throw StatementError::upcast($e);
87 }
88
89 if ($ret === false) {
90 throw StatementError::new($this->statement);
91 }
92
93 if ($ret === null) {
94 return false;
95 }
96
97 $values = [];
98
99 foreach ($this->boundValues as $v) {
100 $values[] = $v;
101 }
102
103 return $values;
104 }
105
106 public function fetchAssociative(): array|false
107 {
108 $values = $this->fetchNumeric();
109
110 if ($values === false) {
111 return false;
112 }
113
114 return array_combine($this->columnNames, $values);
115 }
116
117 public function fetchOne(): mixed
118 {
119 return FetchUtils::fetchOne($this);
120 }
121
122 /**
123 * {@inheritDoc}
124 */
125 public function fetchAllNumeric(): array
126 {
127 return FetchUtils::fetchAllNumeric($this);
128 }
129
130 /**
131 * {@inheritDoc}
132 */
133 public function fetchAllAssociative(): array
134 {
135 return FetchUtils::fetchAllAssociative($this);
136 }
137
138 /**
139 * {@inheritDoc}
140 */
141 public function fetchFirstColumn(): array
142 {
143 return FetchUtils::fetchFirstColumn($this);
144 }
145
146 public function rowCount(): int|string
147 {
148 if ($this->hasColumns) {
149 return $this->statement->num_rows;
150 }
151
152 return $this->statement->affected_rows;
153 }
154
155 public function columnCount(): int
156 {
157 return $this->statement->field_count;
158 }
159
160 public function free(): void
161 {
162 $this->statement->free_result();
163 }
164}
diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Statement.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Statement.php
new file mode 100644
index 0000000..8436fad
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Statement.php
@@ -0,0 +1,154 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\Mysqli;
6
7use Doctrine\DBAL\Driver\Exception;
8use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
9use Doctrine\DBAL\Driver\Mysqli\Exception\NonStreamResourceUsedAsLargeObject;
10use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
11use Doctrine\DBAL\Driver\Statement as StatementInterface;
12use Doctrine\DBAL\ParameterType;
13use mysqli_sql_exception;
14use mysqli_stmt;
15
16use function array_fill;
17use function assert;
18use function count;
19use function feof;
20use function fread;
21use function get_resource_type;
22use function is_int;
23use function is_resource;
24use function str_repeat;
25
26final class Statement implements StatementInterface
27{
28 private const PARAMETER_TYPE_STRING = 's';
29 private const PARAMETER_TYPE_INTEGER = 'i';
30 private const PARAMETER_TYPE_BINARY = 'b';
31
32 /** @var mixed[] */
33 private array $boundValues;
34
35 private string $types;
36
37 /**
38 * Contains ref values for bindValue().
39 *
40 * @var mixed[]
41 */
42 private array $values = [];
43
44 /** @internal The statement can be only instantiated by its driver connection. */
45 public function __construct(private readonly mysqli_stmt $stmt)
46 {
47 $paramCount = $this->stmt->param_count;
48 $this->types = str_repeat(self::PARAMETER_TYPE_STRING, $paramCount);
49 $this->boundValues = array_fill(1, $paramCount, null);
50 }
51
52 public function bindValue(int|string $param, mixed $value, ParameterType $type): void
53 {
54 assert(is_int($param));
55
56 $this->types[$param - 1] = $this->convertParameterType($type);
57 $this->values[$param] = $value;
58 $this->boundValues[$param] =& $this->values[$param];
59 }
60
61 public function execute(): Result
62 {
63 if (count($this->boundValues) > 0) {
64 $this->bindParameters();
65 }
66
67 try {
68 if (! $this->stmt->execute()) {
69 throw StatementError::new($this->stmt);
70 }
71 } catch (mysqli_sql_exception $e) {
72 throw StatementError::upcast($e);
73 }
74
75 return new Result($this->stmt);
76 }
77
78 /**
79 * Binds parameters with known types previously bound to the statement
80 *
81 * @throws Exception
82 */
83 private function bindParameters(): void
84 {
85 $streams = $values = [];
86 $types = $this->types;
87
88 foreach ($this->boundValues as $parameter => $value) {
89 assert(is_int($parameter));
90 if (! isset($types[$parameter - 1])) {
91 $types[$parameter - 1] = self::PARAMETER_TYPE_STRING;
92 }
93
94 if ($types[$parameter - 1] === self::PARAMETER_TYPE_BINARY) {
95 if (is_resource($value)) {
96 if (get_resource_type($value) !== 'stream') {
97 throw NonStreamResourceUsedAsLargeObject::new($parameter);
98 }
99
100 $streams[$parameter] = $value;
101 $values[$parameter] = null;
102 continue;
103 }
104
105 $types[$parameter - 1] = self::PARAMETER_TYPE_STRING;
106 }
107
108 $values[$parameter] = $value;
109 }
110
111 if (! $this->stmt->bind_param($types, ...$values)) {
112 throw StatementError::new($this->stmt);
113 }
114
115 $this->sendLongData($streams);
116 }
117
118 /**
119 * Handle $this->_longData after regular query parameters have been bound
120 *
121 * @param array<int, resource> $streams
122 *
123 * @throws Exception
124 */
125 private function sendLongData(array $streams): void
126 {
127 foreach ($streams as $paramNr => $stream) {
128 while (! feof($stream)) {
129 $chunk = fread($stream, 8192);
130
131 if ($chunk === false) {
132 throw FailedReadingStreamOffset::new($paramNr);
133 }
134
135 if (! $this->stmt->send_long_data($paramNr - 1, $chunk)) {
136 throw StatementError::new($this->stmt);
137 }
138 }
139 }
140 }
141
142 private function convertParameterType(ParameterType $type): string
143 {
144 return match ($type) {
145 ParameterType::NULL,
146 ParameterType::STRING,
147 ParameterType::ASCII,
148 ParameterType::BINARY => self::PARAMETER_TYPE_STRING,
149 ParameterType::INTEGER,
150 ParameterType::BOOLEAN => self::PARAMETER_TYPE_INTEGER,
151 ParameterType::LARGE_OBJECT => self::PARAMETER_TYPE_BINARY,
152 };
153 }
154}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Connection.php b/vendor/doctrine/dbal/src/Driver/OCI8/Connection.php
new file mode 100644
index 0000000..3652ca0
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Connection.php
@@ -0,0 +1,119 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8;
6
7use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
8use Doctrine\DBAL\Driver\Exception;
9use Doctrine\DBAL\Driver\Exception\IdentityColumnsNotSupported;
10use Doctrine\DBAL\Driver\OCI8\Exception\Error;
11use Doctrine\DBAL\SQL\Parser;
12
13use function addcslashes;
14use function assert;
15use function is_resource;
16use function oci_commit;
17use function oci_parse;
18use function oci_rollback;
19use function oci_server_version;
20use function preg_match;
21use function str_replace;
22
23final class Connection implements ConnectionInterface
24{
25 private readonly Parser $parser;
26 private readonly ExecutionMode $executionMode;
27
28 /**
29 * @internal The connection can be only instantiated by its driver.
30 *
31 * @param resource $connection
32 */
33 public function __construct(private readonly mixed $connection)
34 {
35 $this->parser = new Parser(false);
36 $this->executionMode = new ExecutionMode();
37 }
38
39 public function getServerVersion(): string
40 {
41 $version = oci_server_version($this->connection);
42 assert($version !== false);
43
44 $result = preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches);
45 assert($result === 1);
46
47 return $matches[1];
48 }
49
50 /** @throws Parser\Exception */
51 public function prepare(string $sql): Statement
52 {
53 $visitor = new ConvertPositionalToNamedPlaceholders();
54
55 $this->parser->parse($sql, $visitor);
56
57 $statement = oci_parse($this->connection, $visitor->getSQL());
58 assert(is_resource($statement));
59
60 return new Statement($this->connection, $statement, $visitor->getParameterMap(), $this->executionMode);
61 }
62
63 /**
64 * @throws Exception
65 * @throws Parser\Exception
66 */
67 public function query(string $sql): Result
68 {
69 return $this->prepare($sql)->execute();
70 }
71
72 public function quote(string $value): string
73 {
74 return "'" . addcslashes(str_replace("'", "''", $value), "\000\n\r\\\032") . "'";
75 }
76
77 /**
78 * @throws Exception
79 * @throws Parser\Exception
80 */
81 public function exec(string $sql): int|string
82 {
83 return $this->prepare($sql)->execute()->rowCount();
84 }
85
86 public function lastInsertId(): int|string
87 {
88 throw IdentityColumnsNotSupported::new();
89 }
90
91 public function beginTransaction(): void
92 {
93 $this->executionMode->disableAutoCommit();
94 }
95
96 public function commit(): void
97 {
98 if (! oci_commit($this->connection)) {
99 throw Error::new($this->connection);
100 }
101
102 $this->executionMode->enableAutoCommit();
103 }
104
105 public function rollBack(): void
106 {
107 if (! oci_rollback($this->connection)) {
108 throw Error::new($this->connection);
109 }
110
111 $this->executionMode->enableAutoCommit();
112 }
113
114 /** @return resource */
115 public function getNativeConnection()
116 {
117 return $this->connection;
118 }
119}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/ConvertPositionalToNamedPlaceholders.php b/vendor/doctrine/dbal/src/Driver/OCI8/ConvertPositionalToNamedPlaceholders.php
new file mode 100644
index 0000000..5898a2c
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/ConvertPositionalToNamedPlaceholders.php
@@ -0,0 +1,58 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8;
6
7use Doctrine\DBAL\SQL\Parser\Visitor;
8
9use function count;
10use function implode;
11
12/**
13 * Converts positional (?) into named placeholders (:param<num>).
14 *
15 * Oracle does not support positional parameters, hence this method converts all
16 * positional parameters into artificially named parameters.
17 *
18 * @internal This class is not covered by the backward compatibility promise
19 */
20final class ConvertPositionalToNamedPlaceholders implements Visitor
21{
22 /** @var list<string> */
23 private array $buffer = [];
24
25 /** @var array<int,string> */
26 private array $parameterMap = [];
27
28 public function acceptOther(string $sql): void
29 {
30 $this->buffer[] = $sql;
31 }
32
33 public function acceptPositionalParameter(string $sql): void
34 {
35 $position = count($this->parameterMap) + 1;
36 $param = ':param' . $position;
37
38 $this->parameterMap[$position] = $param;
39
40 $this->buffer[] = $param;
41 }
42
43 public function acceptNamedParameter(string $sql): void
44 {
45 $this->buffer[] = $sql;
46 }
47
48 public function getSQL(): string
49 {
50 return implode('', $this->buffer);
51 }
52
53 /** @return array<int,string> */
54 public function getParameterMap(): array
55 {
56 return $this->parameterMap;
57 }
58}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Driver.php b/vendor/doctrine/dbal/src/Driver/OCI8/Driver.php
new file mode 100644
index 0000000..1b0afbf
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Driver.php
@@ -0,0 +1,60 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8;
6
7use Doctrine\DBAL\Driver\AbstractOracleDriver;
8use Doctrine\DBAL\Driver\OCI8\Exception\ConnectionFailed;
9use Doctrine\DBAL\Driver\OCI8\Exception\InvalidConfiguration;
10use SensitiveParameter;
11
12use function oci_connect;
13use function oci_new_connect;
14use function oci_pconnect;
15
16use const OCI_NO_AUTO_COMMIT;
17
18/**
19 * A Doctrine DBAL driver for the Oracle OCI8 PHP extensions.
20 */
21final class Driver extends AbstractOracleDriver
22{
23 /**
24 * {@inheritDoc}
25 */
26 public function connect(
27 #[SensitiveParameter]
28 array $params,
29 ): Connection {
30 $username = $params['user'] ?? '';
31 $password = $params['password'] ?? '';
32 $charset = $params['charset'] ?? '';
33 $sessionMode = $params['sessionMode'] ?? OCI_NO_AUTO_COMMIT;
34
35 $connectionString = $this->getEasyConnectString($params);
36
37 /** @psalm-suppress RiskyTruthyFalsyComparison */
38 $persistent = ! empty($params['persistent']);
39 /** @psalm-suppress RiskyTruthyFalsyComparison */
40 $exclusive = ! empty($params['driverOptions']['exclusive']);
41
42 if ($persistent && $exclusive) {
43 throw InvalidConfiguration::forPersistentAndExclusive();
44 }
45
46 if ($persistent) {
47 $connection = @oci_pconnect($username, $password, $connectionString, $charset, $sessionMode);
48 } elseif ($exclusive) {
49 $connection = @oci_new_connect($username, $password, $connectionString, $charset, $sessionMode);
50 } else {
51 $connection = @oci_connect($username, $password, $connectionString, $charset, $sessionMode);
52 }
53
54 if ($connection === false) {
55 throw ConnectionFailed::new();
56 }
57
58 return new Connection($connection);
59 }
60}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php
new file mode 100644
index 0000000..cefe9a3
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php
@@ -0,0 +1,26 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function assert;
10use function oci_error;
11
12/**
13 * @internal
14 *
15 * @psalm-immutable
16 */
17final class ConnectionFailed extends AbstractException
18{
19 public static function new(): self
20 {
21 $error = oci_error();
22 assert($error !== false);
23
24 return new self($error['message'], null, $error['code']);
25 }
26}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Exception/Error.php b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/Error.php
new file mode 100644
index 0000000..6abdf23
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/Error.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function assert;
10use function oci_error;
11
12/**
13 * @internal
14 *
15 * @psalm-immutable
16 */
17final class Error extends AbstractException
18{
19 /** @param resource $resource */
20 public static function new($resource): self
21 {
22 $error = oci_error($resource);
23 assert($error !== false);
24
25 return new self($error['message'], null, $error['code']);
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php
new file mode 100644
index 0000000..e9d2d0e
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/InvalidConfiguration.php
@@ -0,0 +1,20 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9/**
10 * @internal
11 *
12 * @psalm-immutable
13 */
14final class InvalidConfiguration extends AbstractException
15{
16 public static function forPersistentAndExclusive(): self
17 {
18 return new self('The "persistent" parameter and the "exclusive" driver option are mutually exclusive');
19 }
20}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Exception/NonTerminatedStringLiteral.php b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/NonTerminatedStringLiteral.php
new file mode 100644
index 0000000..776728f
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/NonTerminatedStringLiteral.php
@@ -0,0 +1,27 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function sprintf;
10
11/**
12 * @internal
13 *
14 * @psalm-immutable
15 */
16final class NonTerminatedStringLiteral extends AbstractException
17{
18 public static function new(int $offset): self
19 {
20 return new self(
21 sprintf(
22 'The statement contains non-terminated string literal starting at offset %d.',
23 $offset,
24 ),
25 );
26 }
27}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Exception/UnknownParameterIndex.php b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/UnknownParameterIndex.php
new file mode 100644
index 0000000..2cd3fe7
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/UnknownParameterIndex.php
@@ -0,0 +1,24 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function sprintf;
10
11/**
12 * @internal
13 *
14 * @psalm-immutable
15 */
16final class UnknownParameterIndex extends AbstractException
17{
18 public static function new(int $index): self
19 {
20 return new self(
21 sprintf('Could not find variable mapping with index %d, in the SQL statement', $index),
22 );
23 }
24}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/ExecutionMode.php b/vendor/doctrine/dbal/src/Driver/OCI8/ExecutionMode.php
new file mode 100644
index 0000000..8efb936
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/ExecutionMode.php
@@ -0,0 +1,30 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8;
6
7/**
8 * Encapsulates the execution mode that is shared between the connection and its statements.
9 *
10 * @internal This class is not covered by the backward compatibility promise
11 */
12final class ExecutionMode
13{
14 private bool $isAutoCommitEnabled = true;
15
16 public function enableAutoCommit(): void
17 {
18 $this->isAutoCommitEnabled = true;
19 }
20
21 public function disableAutoCommit(): void
22 {
23 $this->isAutoCommitEnabled = false;
24 }
25
26 public function isAutoCommitEnabled(): bool
27 {
28 return $this->isAutoCommitEnabled;
29 }
30}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php b/vendor/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php
new file mode 100644
index 0000000..b825a1a
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php
@@ -0,0 +1,40 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8\Middleware;
6
7use Doctrine\DBAL\Driver;
8use Doctrine\DBAL\Driver\Connection;
9use Doctrine\DBAL\Driver\Middleware;
10use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
11use SensitiveParameter;
12
13final class InitializeSession implements Middleware
14{
15 public function wrap(Driver $driver): Driver
16 {
17 return new class ($driver) extends AbstractDriverMiddleware {
18 /**
19 * {@inheritDoc}
20 */
21 public function connect(
22 #[SensitiveParameter]
23 array $params,
24 ): Connection {
25 $connection = parent::connect($params);
26
27 $connection->exec(
28 'ALTER SESSION SET'
29 . " NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
30 . " NLS_TIME_FORMAT = 'HH24:MI:SS'"
31 . " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
32 . " NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS TZH:TZM'"
33 . " NLS_NUMERIC_CHARACTERS = '.,'",
34 );
35
36 return $connection;
37 }
38 };
39 }
40}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Result.php b/vendor/doctrine/dbal/src/Driver/OCI8/Result.php
new file mode 100644
index 0000000..609e651
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Result.php
@@ -0,0 +1,128 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8;
6
7use Doctrine\DBAL\Driver\Exception;
8use Doctrine\DBAL\Driver\FetchUtils;
9use Doctrine\DBAL\Driver\OCI8\Exception\Error;
10use Doctrine\DBAL\Driver\Result as ResultInterface;
11
12use function oci_cancel;
13use function oci_error;
14use function oci_fetch_all;
15use function oci_fetch_array;
16use function oci_num_fields;
17use function oci_num_rows;
18
19use const OCI_ASSOC;
20use const OCI_FETCHSTATEMENT_BY_COLUMN;
21use const OCI_FETCHSTATEMENT_BY_ROW;
22use const OCI_NUM;
23use const OCI_RETURN_LOBS;
24use const OCI_RETURN_NULLS;
25
26final class Result implements ResultInterface
27{
28 /**
29 * @internal The result can be only instantiated by its driver connection or statement.
30 *
31 * @param resource $statement
32 */
33 public function __construct(private readonly mixed $statement)
34 {
35 }
36
37 public function fetchNumeric(): array|false
38 {
39 return $this->fetch(OCI_NUM);
40 }
41
42 public function fetchAssociative(): array|false
43 {
44 return $this->fetch(OCI_ASSOC);
45 }
46
47 public function fetchOne(): mixed
48 {
49 return FetchUtils::fetchOne($this);
50 }
51
52 /**
53 * {@inheritDoc}
54 */
55 public function fetchAllNumeric(): array
56 {
57 return $this->fetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_ROW);
58 }
59
60 /**
61 * {@inheritDoc}
62 */
63 public function fetchAllAssociative(): array
64 {
65 return $this->fetchAll(OCI_ASSOC, OCI_FETCHSTATEMENT_BY_ROW);
66 }
67
68 /**
69 * {@inheritDoc}
70 */
71 public function fetchFirstColumn(): array
72 {
73 return $this->fetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_COLUMN)[0];
74 }
75
76 public function rowCount(): int
77 {
78 $count = oci_num_rows($this->statement);
79
80 if ($count !== false) {
81 return $count;
82 }
83
84 return 0;
85 }
86
87 public function columnCount(): int
88 {
89 $count = oci_num_fields($this->statement);
90
91 if ($count !== false) {
92 return $count;
93 }
94
95 return 0;
96 }
97
98 public function free(): void
99 {
100 oci_cancel($this->statement);
101 }
102
103 /** @throws Exception */
104 private function fetch(int $mode): mixed
105 {
106 $result = oci_fetch_array($this->statement, $mode | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
107
108 if ($result === false && oci_error($this->statement) !== false) {
109 throw Error::new($this->statement);
110 }
111
112 return $result;
113 }
114
115 /** @return array<mixed> */
116 private function fetchAll(int $mode, int $fetchStructure): array
117 {
118 oci_fetch_all(
119 $this->statement,
120 $result,
121 0,
122 -1,
123 $mode | OCI_RETURN_NULLS | $fetchStructure | OCI_RETURN_LOBS,
124 );
125
126 return $result;
127 }
128}
diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Statement.php b/vendor/doctrine/dbal/src/Driver/OCI8/Statement.php
new file mode 100644
index 0000000..408f0dd
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/OCI8/Statement.php
@@ -0,0 +1,103 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\OCI8;
6
7use Doctrine\DBAL\Driver\OCI8\Exception\Error;
8use Doctrine\DBAL\Driver\OCI8\Exception\UnknownParameterIndex;
9use Doctrine\DBAL\Driver\Statement as StatementInterface;
10use Doctrine\DBAL\ParameterType;
11
12use function is_int;
13use function oci_bind_by_name;
14use function oci_execute;
15use function oci_new_descriptor;
16
17use const OCI_B_BIN;
18use const OCI_B_BLOB;
19use const OCI_COMMIT_ON_SUCCESS;
20use const OCI_D_LOB;
21use const OCI_NO_AUTO_COMMIT;
22use const OCI_TEMP_BLOB;
23use const SQLT_CHR;
24
25final class Statement implements StatementInterface
26{
27 /**
28 * @internal The statement can be only instantiated by its driver connection.
29 *
30 * @param resource $connection
31 * @param resource $statement
32 * @param array<int,string> $parameterMap
33 */
34 public function __construct(
35 private readonly mixed $connection,
36 private readonly mixed $statement,
37 private readonly array $parameterMap,
38 private readonly ExecutionMode $executionMode,
39 ) {
40 }
41
42 public function bindValue(int|string $param, mixed $value, ParameterType $type): void
43 {
44 if (is_int($param)) {
45 if (! isset($this->parameterMap[$param])) {
46 throw UnknownParameterIndex::new($param);
47 }
48
49 $param = $this->parameterMap[$param];
50 }
51
52 if ($type === ParameterType::LARGE_OBJECT) {
53 if ($value !== null) {
54 $lob = oci_new_descriptor($this->connection, OCI_D_LOB);
55 $lob->writeTemporary($value, OCI_TEMP_BLOB);
56
57 $value =& $lob;
58 } else {
59 $type = ParameterType::STRING;
60 }
61 }
62
63 if (
64 ! @oci_bind_by_name(
65 $this->statement,
66 $param,
67 $value,
68 -1,
69 $this->convertParameterType($type),
70 )
71 ) {
72 throw Error::new($this->statement);
73 }
74 }
75
76 /**
77 * Converts DBAL parameter type to oci8 parameter type
78 */
79 private function convertParameterType(ParameterType $type): int
80 {
81 return match ($type) {
82 ParameterType::BINARY => OCI_B_BIN,
83 ParameterType::LARGE_OBJECT => OCI_B_BLOB,
84 default => SQLT_CHR,
85 };
86 }
87
88 public function execute(): Result
89 {
90 if ($this->executionMode->isAutoCommitEnabled()) {
91 $mode = OCI_COMMIT_ON_SUCCESS;
92 } else {
93 $mode = OCI_NO_AUTO_COMMIT;
94 }
95
96 $ret = @oci_execute($this->statement, $mode);
97 if (! $ret) {
98 throw Error::new($this->statement);
99 }
100
101 return new Result($this->statement);
102 }
103}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/Connection.php b/vendor/doctrine/dbal/src/Driver/PDO/Connection.php
new file mode 100644
index 0000000..b1faca1
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/Connection.php
@@ -0,0 +1,133 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO;
6
7use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
8use Doctrine\DBAL\Driver\Exception\IdentityColumnsNotSupported;
9use Doctrine\DBAL\Driver\Exception\NoIdentityValue;
10use PDO;
11use PDOException;
12use PDOStatement;
13
14use function assert;
15
16final class Connection implements ConnectionInterface
17{
18 /** @internal The connection can be only instantiated by its driver. */
19 public function __construct(private readonly PDO $connection)
20 {
21 $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
22 }
23
24 public function exec(string $sql): int
25 {
26 try {
27 $result = $this->connection->exec($sql);
28
29 assert($result !== false);
30
31 return $result;
32 } catch (PDOException $exception) {
33 throw Exception::new($exception);
34 }
35 }
36
37 public function getServerVersion(): string
38 {
39 return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
40 }
41
42 public function prepare(string $sql): Statement
43 {
44 try {
45 $stmt = $this->connection->prepare($sql);
46 assert($stmt instanceof PDOStatement);
47
48 return new Statement($stmt);
49 } catch (PDOException $exception) {
50 throw Exception::new($exception);
51 }
52 }
53
54 public function query(string $sql): Result
55 {
56 try {
57 $stmt = $this->connection->query($sql);
58 assert($stmt instanceof PDOStatement);
59
60 return new Result($stmt);
61 } catch (PDOException $exception) {
62 throw Exception::new($exception);
63 }
64 }
65
66 public function quote(string $value): string
67 {
68 return $this->connection->quote($value);
69 }
70
71 public function lastInsertId(): int|string
72 {
73 try {
74 $value = $this->connection->lastInsertId();
75 } catch (PDOException $exception) {
76 assert($exception->errorInfo !== null);
77 [$sqlState] = $exception->errorInfo;
78
79 // if the PDO driver does not support this capability, PDO::lastInsertId() triggers an IM001 SQLSTATE
80 // see https://www.php.net/manual/en/pdo.lastinsertid.php
81 if ($sqlState === 'IM001') {
82 throw IdentityColumnsNotSupported::new();
83 }
84
85 // PDO PGSQL throws a 'lastval is not yet defined in this session' error when no identity value is
86 // available, with SQLSTATE 55000 'Object Not In Prerequisite State'
87 if ($sqlState === '55000' && $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME) === 'pgsql') {
88 throw NoIdentityValue::new($exception);
89 }
90
91 throw Exception::new($exception);
92 }
93
94 // pdo_mysql & pdo_sqlite return '0', pdo_sqlsrv returns '' or false depending on the PHP version
95 if ($value === '0' || $value === '' || $value === false) {
96 throw NoIdentityValue::new();
97 }
98
99 return $value;
100 }
101
102 public function beginTransaction(): void
103 {
104 try {
105 $this->connection->beginTransaction();
106 } catch (PDOException $exception) {
107 throw Exception::new($exception);
108 }
109 }
110
111 public function commit(): void
112 {
113 try {
114 $this->connection->commit();
115 } catch (PDOException $exception) {
116 throw Exception::new($exception);
117 }
118 }
119
120 public function rollBack(): void
121 {
122 try {
123 $this->connection->rollBack();
124 } catch (PDOException $exception) {
125 throw Exception::new($exception);
126 }
127 }
128
129 public function getNativeConnection(): PDO
130 {
131 return $this->connection;
132 }
133}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/Exception.php b/vendor/doctrine/dbal/src/Driver/PDO/Exception.php
new file mode 100644
index 0000000..fbb8125
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/Exception.php
@@ -0,0 +1,30 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO;
6
7use Doctrine\DBAL\Driver\AbstractException;
8use PDOException;
9
10/**
11 * @internal
12 *
13 * @psalm-immutable
14 */
15final class Exception extends AbstractException
16{
17 public static function new(PDOException $exception): self
18 {
19 if ($exception->errorInfo !== null) {
20 [$sqlState, $code] = $exception->errorInfo;
21
22 $code ??= 0;
23 } else {
24 $code = $exception->getCode();
25 $sqlState = null;
26 }
27
28 return new self($exception->getMessage(), $sqlState, $code, $exception);
29 }
30}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php
new file mode 100644
index 0000000..963fef0
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php
@@ -0,0 +1,76 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO\MySQL;
6
7use Doctrine\DBAL\Driver\AbstractMySQLDriver;
8use Doctrine\DBAL\Driver\PDO\Connection;
9use Doctrine\DBAL\Driver\PDO\Exception;
10use PDO;
11use PDOException;
12use SensitiveParameter;
13
14final class Driver extends AbstractMySQLDriver
15{
16 /**
17 * {@inheritDoc}
18 */
19 public function connect(
20 #[SensitiveParameter]
21 array $params,
22 ): Connection {
23 $driverOptions = $params['driverOptions'] ?? [];
24
25 if (! empty($params['persistent'])) {
26 $driverOptions[PDO::ATTR_PERSISTENT] = true;
27 }
28
29 $safeParams = $params;
30 unset($safeParams['password']);
31
32 try {
33 $pdo = new PDO(
34 $this->constructPdoDsn($safeParams),
35 $params['user'] ?? '',
36 $params['password'] ?? '',
37 $driverOptions,
38 );
39 } catch (PDOException $exception) {
40 throw Exception::new($exception);
41 }
42
43 return new Connection($pdo);
44 }
45
46 /**
47 * Constructs the MySQL PDO DSN.
48 *
49 * @param mixed[] $params
50 */
51 private function constructPdoDsn(array $params): string
52 {
53 $dsn = 'mysql:';
54 if (isset($params['host']) && $params['host'] !== '') {
55 $dsn .= 'host=' . $params['host'] . ';';
56 }
57
58 if (isset($params['port'])) {
59 $dsn .= 'port=' . $params['port'] . ';';
60 }
61
62 if (isset($params['dbname'])) {
63 $dsn .= 'dbname=' . $params['dbname'] . ';';
64 }
65
66 if (isset($params['unix_socket'])) {
67 $dsn .= 'unix_socket=' . $params['unix_socket'] . ';';
68 }
69
70 if (isset($params['charset'])) {
71 $dsn .= 'charset=' . $params['charset'] . ';';
72 }
73
74 return $dsn;
75 }
76}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/OCI/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/OCI/Driver.php
new file mode 100644
index 0000000..4c02de1
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/OCI/Driver.php
@@ -0,0 +1,61 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO\OCI;
6
7use Doctrine\DBAL\Driver\AbstractOracleDriver;
8use Doctrine\DBAL\Driver\PDO\Connection;
9use Doctrine\DBAL\Driver\PDO\Exception;
10use PDO;
11use PDOException;
12use SensitiveParameter;
13
14final class Driver extends AbstractOracleDriver
15{
16 /**
17 * {@inheritDoc}
18 */
19 public function connect(
20 #[SensitiveParameter]
21 array $params,
22 ): Connection {
23 $driverOptions = $params['driverOptions'] ?? [];
24
25 if (! empty($params['persistent'])) {
26 $driverOptions[PDO::ATTR_PERSISTENT] = true;
27 }
28
29 $safeParams = $params;
30 unset($safeParams['password']);
31
32 try {
33 $pdo = new PDO(
34 $this->constructPdoDsn($params),
35 $params['user'] ?? '',
36 $params['password'] ?? '',
37 $driverOptions,
38 );
39 } catch (PDOException $exception) {
40 throw Exception::new($exception);
41 }
42
43 return new Connection($pdo);
44 }
45
46 /**
47 * Constructs the Oracle PDO DSN.
48 *
49 * @param mixed[] $params
50 */
51 private function constructPdoDsn(array $params): string
52 {
53 $dsn = 'oci:dbname=' . $this->getEasyConnectString($params);
54
55 if (isset($params['charset'])) {
56 $dsn .= ';charset=' . $params['charset'];
57 }
58
59 return $dsn;
60 }
61}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php
new file mode 100644
index 0000000..a267e84
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php
@@ -0,0 +1,113 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO\PgSQL;
6
7use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver;
8use Doctrine\DBAL\Driver\PDO\Connection;
9use Doctrine\DBAL\Driver\PDO\Exception;
10use PDO;
11use PDOException;
12use SensitiveParameter;
13
14final class Driver extends AbstractPostgreSQLDriver
15{
16 /**
17 * {@inheritDoc}
18 */
19 public function connect(
20 #[SensitiveParameter]
21 array $params,
22 ): Connection {
23 $driverOptions = $params['driverOptions'] ?? [];
24
25 if (! empty($params['persistent'])) {
26 $driverOptions[PDO::ATTR_PERSISTENT] = true;
27 }
28
29 $safeParams = $params;
30 unset($safeParams['password']);
31
32 try {
33 $pdo = new PDO(
34 $this->constructPdoDsn($safeParams),
35 $params['user'] ?? '',
36 $params['password'] ?? '',
37 $driverOptions,
38 );
39 } catch (PDOException $exception) {
40 throw Exception::new($exception);
41 }
42
43 if (
44 ! isset($driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES])
45 || $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true
46 ) {
47 $pdo->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true);
48 }
49
50 $connection = new Connection($pdo);
51
52 /* defining client_encoding via SET NAMES to avoid inconsistent DSN support
53 * - passing client_encoding via the 'options' param breaks pgbouncer support
54 */
55 if (isset($params['charset'])) {
56 $connection->exec('SET NAMES \'' . $params['charset'] . '\'');
57 }
58
59 return $connection;
60 }
61
62 /**
63 * Constructs the Postgres PDO DSN.
64 *
65 * @param array<string, mixed> $params
66 */
67 private function constructPdoDsn(array $params): string
68 {
69 $dsn = 'pgsql:';
70
71 if (isset($params['host']) && $params['host'] !== '') {
72 $dsn .= 'host=' . $params['host'] . ';';
73 }
74
75 if (isset($params['port']) && $params['port'] !== '') {
76 $dsn .= 'port=' . $params['port'] . ';';
77 }
78
79 if (isset($params['dbname'])) {
80 $dsn .= 'dbname=' . $params['dbname'] . ';';
81 }
82
83 if (isset($params['sslmode'])) {
84 $dsn .= 'sslmode=' . $params['sslmode'] . ';';
85 }
86
87 if (isset($params['sslrootcert'])) {
88 $dsn .= 'sslrootcert=' . $params['sslrootcert'] . ';';
89 }
90
91 if (isset($params['sslcert'])) {
92 $dsn .= 'sslcert=' . $params['sslcert'] . ';';
93 }
94
95 if (isset($params['sslkey'])) {
96 $dsn .= 'sslkey=' . $params['sslkey'] . ';';
97 }
98
99 if (isset($params['sslcrl'])) {
100 $dsn .= 'sslcrl=' . $params['sslcrl'] . ';';
101 }
102
103 if (isset($params['application_name'])) {
104 $dsn .= 'application_name=' . $params['application_name'] . ';';
105 }
106
107 if (isset($params['gssencmode'])) {
108 $dsn .= 'gssencmode=' . $params['gssencmode'] . ';';
109 }
110
111 return $dsn;
112 }
113}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/Result.php b/vendor/doctrine/dbal/src/Driver/PDO/Result.php
new file mode 100644
index 0000000..1a844d1
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/Result.php
@@ -0,0 +1,110 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO;
6
7use Doctrine\DBAL\Driver\Result as ResultInterface;
8use PDO;
9use PDOException;
10use PDOStatement;
11
12final class Result implements ResultInterface
13{
14 /** @internal The result can be only instantiated by its driver connection or statement. */
15 public function __construct(private readonly PDOStatement $statement)
16 {
17 }
18
19 public function fetchNumeric(): array|false
20 {
21 return $this->fetch(PDO::FETCH_NUM);
22 }
23
24 public function fetchAssociative(): array|false
25 {
26 return $this->fetch(PDO::FETCH_ASSOC);
27 }
28
29 public function fetchOne(): mixed
30 {
31 return $this->fetch(PDO::FETCH_COLUMN);
32 }
33
34 /**
35 * {@inheritDoc}
36 */
37 public function fetchAllNumeric(): array
38 {
39 return $this->fetchAll(PDO::FETCH_NUM);
40 }
41
42 /**
43 * {@inheritDoc}
44 */
45 public function fetchAllAssociative(): array
46 {
47 return $this->fetchAll(PDO::FETCH_ASSOC);
48 }
49
50 /**
51 * {@inheritDoc}
52 */
53 public function fetchFirstColumn(): array
54 {
55 return $this->fetchAll(PDO::FETCH_COLUMN);
56 }
57
58 public function rowCount(): int
59 {
60 try {
61 return $this->statement->rowCount();
62 } catch (PDOException $exception) {
63 throw Exception::new($exception);
64 }
65 }
66
67 public function columnCount(): int
68 {
69 try {
70 return $this->statement->columnCount();
71 } catch (PDOException $exception) {
72 throw Exception::new($exception);
73 }
74 }
75
76 public function free(): void
77 {
78 $this->statement->closeCursor();
79 }
80
81 /**
82 * @psalm-param PDO::FETCH_* $mode
83 *
84 * @throws Exception
85 */
86 private function fetch(int $mode): mixed
87 {
88 try {
89 return $this->statement->fetch($mode);
90 } catch (PDOException $exception) {
91 throw Exception::new($exception);
92 }
93 }
94
95 /**
96 * @psalm-param PDO::FETCH_* $mode
97 *
98 * @return list<mixed>
99 *
100 * @throws Exception
101 */
102 private function fetchAll(int $mode): array
103 {
104 try {
105 return $this->statement->fetchAll($mode);
106 } catch (PDOException $exception) {
107 throw Exception::new($exception);
108 }
109 }
110}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php
new file mode 100644
index 0000000..78ba7f8
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php
@@ -0,0 +1,29 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO\SQLSrv;
6
7use Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware;
8use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
9use PDO;
10
11final class Connection extends AbstractConnectionMiddleware
12{
13 public function __construct(private readonly PDOConnection $connection)
14 {
15 parent::__construct($connection);
16 }
17
18 public function prepare(string $sql): Statement
19 {
20 return new Statement(
21 $this->connection->prepare($sql),
22 );
23 }
24
25 public function getNativeConnection(): PDO
26 {
27 return $this->connection->getNativeConnection();
28 }
29}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php
new file mode 100644
index 0000000..a3cae97
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php
@@ -0,0 +1,108 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO\SQLSrv;
6
7use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
8use Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception\PortWithoutHost;
9use Doctrine\DBAL\Driver\Exception;
10use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
11use Doctrine\DBAL\Driver\PDO\Exception as PDOException;
12use PDO;
13use SensitiveParameter;
14
15use function is_int;
16use function sprintf;
17
18final class Driver extends AbstractSQLServerDriver
19{
20 /**
21 * {@inheritDoc}
22 */
23 public function connect(
24 #[SensitiveParameter]
25 array $params,
26 ): Connection {
27 $driverOptions = $dsnOptions = [];
28
29 if (isset($params['driverOptions'])) {
30 foreach ($params['driverOptions'] as $option => $value) {
31 if (is_int($option)) {
32 $driverOptions[$option] = $value;
33 } else {
34 $dsnOptions[$option] = $value;
35 }
36 }
37 }
38
39 if (! empty($params['persistent'])) {
40 $driverOptions[PDO::ATTR_PERSISTENT] = true;
41 }
42
43 $safeParams = $params;
44 unset($safeParams['password']);
45
46 try {
47 $pdo = new PDO(
48 $this->constructDsn($safeParams, $dsnOptions),
49 $params['user'] ?? '',
50 $params['password'] ?? '',
51 $driverOptions,
52 );
53 } catch (\PDOException $exception) {
54 throw PDOException::new($exception);
55 }
56
57 return new Connection(new PDOConnection($pdo));
58 }
59
60 /**
61 * Constructs the Sqlsrv PDO DSN.
62 *
63 * @param mixed[] $params
64 * @param string[] $connectionOptions
65 *
66 * @throws Exception
67 */
68 private function constructDsn(array $params, array $connectionOptions): string
69 {
70 $dsn = 'sqlsrv:server=';
71
72 if (isset($params['host'])) {
73 $dsn .= $params['host'];
74
75 if (isset($params['port'])) {
76 $dsn .= ',' . $params['port'];
77 }
78 } elseif (isset($params['port'])) {
79 throw PortWithoutHost::new();
80 }
81
82 if (isset($params['dbname'])) {
83 $connectionOptions['Database'] = $params['dbname'];
84 }
85
86 if (isset($params['MultipleActiveResultSets'])) {
87 $connectionOptions['MultipleActiveResultSets'] = $params['MultipleActiveResultSets'] ? 'true' : 'false';
88 }
89
90 return $dsn . $this->getConnectionOptionsDsn($connectionOptions);
91 }
92
93 /**
94 * Converts a connection options array to the DSN
95 *
96 * @param string[] $connectionOptions
97 */
98 private function getConnectionOptionsDsn(array $connectionOptions): string
99 {
100 $connectionOptionsDsn = '';
101
102 foreach ($connectionOptions as $paramName => $paramValue) {
103 $connectionOptionsDsn .= sprintf(';%s=%s', $paramName, $paramValue);
104 }
105
106 return $connectionOptionsDsn;
107 }
108}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php
new file mode 100644
index 0000000..44cecc9
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php
@@ -0,0 +1,46 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO\SQLSrv;
6
7use Doctrine\DBAL\Driver\Middleware\AbstractStatementMiddleware;
8use Doctrine\DBAL\Driver\PDO\Statement as PDOStatement;
9use Doctrine\DBAL\ParameterType;
10use PDO;
11
12final class Statement extends AbstractStatementMiddleware
13{
14 /** @internal The statement can be only instantiated by its driver connection. */
15 public function __construct(private readonly PDOStatement $statement)
16 {
17 parent::__construct($statement);
18 }
19
20 public function bindValue(int|string $param, mixed $value, ParameterType $type): void
21 {
22 switch ($type) {
23 case ParameterType::LARGE_OBJECT:
24 case ParameterType::BINARY:
25 $this->statement->bindParamWithDriverOptions(
26 $param,
27 $value,
28 $type,
29 PDO::SQLSRV_ENCODING_BINARY,
30 );
31 break;
32
33 case ParameterType::ASCII:
34 $this->statement->bindParamWithDriverOptions(
35 $param,
36 $value,
37 ParameterType::STRING,
38 PDO::SQLSRV_ENCODING_SYSTEM,
39 );
40 break;
41
42 default:
43 $this->statement->bindValue($param, $value, $type);
44 }
45 }
46}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php
new file mode 100644
index 0000000..74194a5
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php
@@ -0,0 +1,55 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO\SQLite;
6
7use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
8use Doctrine\DBAL\Driver\PDO\Connection;
9use Doctrine\DBAL\Driver\PDO\Exception;
10use PDO;
11use PDOException;
12use SensitiveParameter;
13
14use function array_intersect_key;
15
16final class Driver extends AbstractSQLiteDriver
17{
18 /**
19 * {@inheritDoc}
20 */
21 public function connect(
22 #[SensitiveParameter]
23 array $params,
24 ): Connection {
25 try {
26 $pdo = new PDO(
27 $this->constructPdoDsn(array_intersect_key($params, ['path' => true, 'memory' => true])),
28 $params['user'] ?? '',
29 $params['password'] ?? '',
30 $params['driverOptions'] ?? [],
31 );
32 } catch (PDOException $exception) {
33 throw Exception::new($exception);
34 }
35
36 return new Connection($pdo);
37 }
38
39 /**
40 * Constructs the Sqlite PDO DSN.
41 *
42 * @param array<string, mixed> $params
43 */
44 private function constructPdoDsn(array $params): string
45 {
46 $dsn = 'sqlite:';
47 if (isset($params['path'])) {
48 $dsn .= $params['path'];
49 } elseif (isset($params['memory'])) {
50 $dsn .= ':memory:';
51 }
52
53 return $dsn;
54 }
55}
diff --git a/vendor/doctrine/dbal/src/Driver/PDO/Statement.php b/vendor/doctrine/dbal/src/Driver/PDO/Statement.php
new file mode 100644
index 0000000..4f0e070
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PDO/Statement.php
@@ -0,0 +1,80 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PDO;
6
7use Doctrine\DBAL\Driver\Exception as ExceptionInterface;
8use Doctrine\DBAL\Driver\Statement as StatementInterface;
9use Doctrine\DBAL\ParameterType;
10use PDO;
11use PDOException;
12use PDOStatement;
13
14final class Statement implements StatementInterface
15{
16 /** @internal The statement can be only instantiated by its driver connection. */
17 public function __construct(private readonly PDOStatement $stmt)
18 {
19 }
20
21 public function bindValue(int|string $param, mixed $value, ParameterType $type): void
22 {
23 $pdoType = $this->convertParamType($type);
24
25 try {
26 $this->stmt->bindValue($param, $value, $pdoType);
27 } catch (PDOException $exception) {
28 throw Exception::new($exception);
29 }
30 }
31
32 /**
33 * @internal Driver options can be only specified by a PDO-based driver.
34 *
35 * @throws ExceptionInterface
36 */
37 public function bindParamWithDriverOptions(
38 string|int $param,
39 mixed &$variable,
40 ParameterType $type,
41 mixed $driverOptions,
42 ): void {
43 $pdoType = $this->convertParamType($type);
44
45 try {
46 $this->stmt->bindParam($param, $variable, $pdoType, 0, $driverOptions);
47 } catch (PDOException $exception) {
48 throw Exception::new($exception);
49 }
50 }
51
52 public function execute(): Result
53 {
54 try {
55 $this->stmt->execute();
56 } catch (PDOException $exception) {
57 throw Exception::new($exception);
58 }
59
60 return new Result($this->stmt);
61 }
62
63 /**
64 * Converts DBAL parameter type to PDO parameter type
65 *
66 * @psalm-return PDO::PARAM_*
67 */
68 private function convertParamType(ParameterType $type): int
69 {
70 return match ($type) {
71 ParameterType::NULL => PDO::PARAM_NULL,
72 ParameterType::INTEGER => PDO::PARAM_INT,
73 ParameterType::STRING,
74 ParameterType::ASCII => PDO::PARAM_STR,
75 ParameterType::BINARY,
76 ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
77 ParameterType::BOOLEAN => PDO::PARAM_BOOL,
78 };
79 }
80}
diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Connection.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Connection.php
new file mode 100644
index 0000000..4f280b0
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Connection.php
@@ -0,0 +1,129 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PgSQL;
6
7use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
8use Doctrine\DBAL\Driver\Exception\NoIdentityValue;
9use Doctrine\DBAL\SQL\Parser;
10use PgSql\Connection as PgSqlConnection;
11
12use function assert;
13use function pg_close;
14use function pg_escape_literal;
15use function pg_get_result;
16use function pg_last_error;
17use function pg_result_error;
18use function pg_send_prepare;
19use function pg_send_query;
20use function pg_version;
21use function uniqid;
22
23final class Connection implements ConnectionInterface
24{
25 private readonly Parser $parser;
26
27 public function __construct(private readonly PgSqlConnection $connection)
28 {
29 $this->parser = new Parser(false);
30 }
31
32 public function __destruct()
33 {
34 if (! isset($this->connection)) {
35 return;
36 }
37
38 @pg_close($this->connection);
39 }
40
41 public function prepare(string $sql): Statement
42 {
43 $visitor = new ConvertParameters();
44 $this->parser->parse($sql, $visitor);
45
46 $statementName = uniqid('dbal', true);
47 if (@pg_send_prepare($this->connection, $statementName, $visitor->getSQL()) !== true) {
48 throw new Exception(pg_last_error($this->connection));
49 }
50
51 $result = @pg_get_result($this->connection);
52 assert($result !== false);
53
54 if ((bool) pg_result_error($result)) {
55 throw Exception::fromResult($result);
56 }
57
58 return new Statement($this->connection, $statementName, $visitor->getParameterMap());
59 }
60
61 public function query(string $sql): Result
62 {
63 if (@pg_send_query($this->connection, $sql) !== true) {
64 throw new Exception(pg_last_error($this->connection));
65 }
66
67 $result = @pg_get_result($this->connection);
68 assert($result !== false);
69
70 if ((bool) pg_result_error($result)) {
71 throw Exception::fromResult($result);
72 }
73
74 return new Result($result);
75 }
76
77 /** {@inheritDoc} */
78 public function quote(string $value): string
79 {
80 $quotedValue = pg_escape_literal($this->connection, $value);
81 assert($quotedValue !== false);
82
83 return $quotedValue;
84 }
85
86 public function exec(string $sql): int
87 {
88 return $this->query($sql)->rowCount();
89 }
90
91 /** {@inheritDoc} */
92 public function lastInsertId(): int|string
93 {
94 try {
95 return $this->query('SELECT LASTVAL()')->fetchOne();
96 } catch (Exception $exception) {
97 if ($exception->getSQLState() === '55000') {
98 throw NoIdentityValue::new($exception);
99 }
100
101 throw $exception;
102 }
103 }
104
105 public function beginTransaction(): void
106 {
107 $this->exec('BEGIN');
108 }
109
110 public function commit(): void
111 {
112 $this->exec('COMMIT');
113 }
114
115 public function rollBack(): void
116 {
117 $this->exec('ROLLBACK');
118 }
119
120 public function getServerVersion(): string
121 {
122 return (string) pg_version($this->connection)['server'];
123 }
124
125 public function getNativeConnection(): PgSqlConnection
126 {
127 return $this->connection;
128 }
129}
diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/ConvertParameters.php b/vendor/doctrine/dbal/src/Driver/PgSQL/ConvertParameters.php
new file mode 100644
index 0000000..795f12d
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PgSQL/ConvertParameters.php
@@ -0,0 +1,49 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PgSQL;
6
7use Doctrine\DBAL\SQL\Parser\Visitor;
8
9use function count;
10use function implode;
11
12final class ConvertParameters implements Visitor
13{
14 /** @var list<string> */
15 private array $buffer = [];
16
17 /** @var array<array-key, int> */
18 private array $parameterMap = [];
19
20 public function acceptPositionalParameter(string $sql): void
21 {
22 $position = count($this->parameterMap) + 1;
23 $this->parameterMap[$position] = $position;
24 $this->buffer[] = '$' . $position;
25 }
26
27 public function acceptNamedParameter(string $sql): void
28 {
29 $position = count($this->parameterMap) + 1;
30 $this->parameterMap[$sql] = $position;
31 $this->buffer[] = '$' . $position;
32 }
33
34 public function acceptOther(string $sql): void
35 {
36 $this->buffer[] = $sql;
37 }
38
39 public function getSQL(): string
40 {
41 return implode('', $this->buffer);
42 }
43
44 /** @return array<array-key, int> */
45 public function getParameterMap(): array
46 {
47 return $this->parameterMap;
48 }
49}
diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Driver.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Driver.php
new file mode 100644
index 0000000..0d5d605
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Driver.php
@@ -0,0 +1,88 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PgSQL;
6
7use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver;
8use ErrorException;
9use SensitiveParameter;
10
11use function addslashes;
12use function array_filter;
13use function array_keys;
14use function array_map;
15use function array_slice;
16use function array_values;
17use function func_get_args;
18use function implode;
19use function pg_connect;
20use function restore_error_handler;
21use function set_error_handler;
22use function sprintf;
23
24use const PGSQL_CONNECT_FORCE_NEW;
25
26final class Driver extends AbstractPostgreSQLDriver
27{
28 /** {@inheritDoc} */
29 public function connect(
30 #[SensitiveParameter]
31 array $params,
32 ): Connection {
33 set_error_handler(
34 static function (int $severity, string $message): never {
35 throw new ErrorException($message, 0, $severity, ...array_slice(func_get_args(), 2, 2));
36 },
37 );
38
39 try {
40 $connection = pg_connect($this->constructConnectionString($params), PGSQL_CONNECT_FORCE_NEW);
41 } catch (ErrorException $e) {
42 throw new Exception($e->getMessage(), '08006', 0, $e);
43 } finally {
44 restore_error_handler();
45 }
46
47 if ($connection === false) {
48 throw new Exception('Unable to connect to Postgres server.');
49 }
50
51 $driverConnection = new Connection($connection);
52
53 if (isset($params['application_name'])) {
54 $driverConnection->exec('SET application_name = ' . $driverConnection->quote($params['application_name']));
55 }
56
57 return $driverConnection;
58 }
59
60 /**
61 * Constructs the Postgres connection string
62 *
63 * @param array<string, mixed> $params
64 */
65 private function constructConnectionString(
66 #[SensitiveParameter]
67 array $params,
68 ): string {
69 $components = array_filter(
70 [
71 'host' => $params['host'] ?? null,
72 'port' => $params['port'] ?? null,
73 'dbname' => $params['dbname'] ?? 'postgres',
74 'user' => $params['user'] ?? null,
75 'password' => $params['password'] ?? null,
76 'sslmode' => $params['sslmode'] ?? null,
77 'gssencmode' => $params['gssencmode'] ?? null,
78 ],
79 static fn (int|string|null $value) => $value !== '' && $value !== null,
80 );
81
82 return implode(' ', array_map(
83 static fn (int|string $value, string $key) => sprintf("%s='%s'", $key, addslashes((string) $value)),
84 array_values($components),
85 array_keys($components),
86 ));
87 }
88}
diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Exception.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Exception.php
new file mode 100644
index 0000000..3036e55
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Exception.php
@@ -0,0 +1,31 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PgSQL;
6
7use Doctrine\DBAL\Driver\AbstractException;
8use PgSql\Result as PgSqlResult;
9
10use function pg_result_error_field;
11
12use const PGSQL_DIAG_MESSAGE_PRIMARY;
13use const PGSQL_DIAG_SQLSTATE;
14
15/**
16 * @internal
17 *
18 * @psalm-immutable
19 */
20final class Exception extends AbstractException
21{
22 public static function fromResult(PgSqlResult $result): self
23 {
24 $sqlstate = pg_result_error_field($result, PGSQL_DIAG_SQLSTATE);
25 if ($sqlstate === false) {
26 $sqlstate = null;
27 }
28
29 return new self((string) pg_result_error_field($result, PGSQL_DIAG_MESSAGE_PRIMARY), $sqlstate);
30 }
31}
diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnexpectedValue.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnexpectedValue.php
new file mode 100644
index 0000000..350d80f
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnexpectedValue.php
@@ -0,0 +1,29 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PgSQL\Exception;
6
7use Doctrine\DBAL\Driver\Exception;
8use UnexpectedValueException;
9
10use function sprintf;
11
12/** @psalm-immutable */
13final class UnexpectedValue extends UnexpectedValueException implements Exception
14{
15 public static function new(string $value, string $type): self
16 {
17 return new self(sprintf(
18 'Unexpected value "%s" of type "%s" returned by Postgres',
19 $value,
20 $type,
21 ));
22 }
23
24 /** @return null */
25 public function getSQLState(): string|null
26 {
27 return null;
28 }
29}
diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnknownParameter.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnknownParameter.php
new file mode 100644
index 0000000..549f96d
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnknownParameter.php
@@ -0,0 +1,20 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PgSQL\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function sprintf;
10
11/** @psalm-immutable */
12final class UnknownParameter extends AbstractException
13{
14 public static function new(string $param): self
15 {
16 return new self(
17 sprintf('Could not find parameter %s in the SQL statement', $param),
18 );
19 }
20}
diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Result.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Result.php
new file mode 100644
index 0000000..954758c
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Result.php
@@ -0,0 +1,240 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PgSQL;
6
7use Doctrine\DBAL\Driver\FetchUtils;
8use Doctrine\DBAL\Driver\PgSQL\Exception\UnexpectedValue;
9use Doctrine\DBAL\Driver\Result as ResultInterface;
10use PgSql\Result as PgSqlResult;
11
12use function array_keys;
13use function array_map;
14use function assert;
15use function hex2bin;
16use function pg_affected_rows;
17use function pg_fetch_all;
18use function pg_fetch_all_columns;
19use function pg_fetch_assoc;
20use function pg_fetch_row;
21use function pg_field_name;
22use function pg_field_type;
23use function pg_free_result;
24use function pg_num_fields;
25use function substr;
26
27use const PGSQL_ASSOC;
28use const PGSQL_NUM;
29use const PHP_INT_SIZE;
30
31final class Result implements ResultInterface
32{
33 private ?PgSqlResult $result;
34
35 public function __construct(PgSqlResult $result)
36 {
37 $this->result = $result;
38 }
39
40 public function __destruct()
41 {
42 if (! isset($this->result)) {
43 return;
44 }
45
46 $this->free();
47 }
48
49 /** {@inheritDoc} */
50 public function fetchNumeric(): array|false
51 {
52 if ($this->result === null) {
53 return false;
54 }
55
56 $row = pg_fetch_row($this->result);
57 if ($row === false) {
58 return false;
59 }
60
61 return $this->mapNumericRow($row, $this->fetchNumericColumnTypes());
62 }
63
64 /** {@inheritDoc} */
65 public function fetchAssociative(): array|false
66 {
67 if ($this->result === null) {
68 return false;
69 }
70
71 $row = pg_fetch_assoc($this->result);
72 if ($row === false) {
73 return false;
74 }
75
76 return $this->mapAssociativeRow($row, $this->fetchAssociativeColumnTypes());
77 }
78
79 /** {@inheritDoc} */
80 public function fetchOne(): mixed
81 {
82 return FetchUtils::fetchOne($this);
83 }
84
85 /** {@inheritDoc} */
86 public function fetchAllNumeric(): array
87 {
88 if ($this->result === null) {
89 return [];
90 }
91
92 $types = $this->fetchNumericColumnTypes();
93
94 return array_map(
95 fn (array $row) => $this->mapNumericRow($row, $types),
96 pg_fetch_all($this->result, PGSQL_NUM),
97 );
98 }
99
100 /** {@inheritDoc} */
101 public function fetchAllAssociative(): array
102 {
103 if ($this->result === null) {
104 return [];
105 }
106
107 $types = $this->fetchAssociativeColumnTypes();
108
109 return array_map(
110 fn (array $row) => $this->mapAssociativeRow($row, $types),
111 pg_fetch_all($this->result, PGSQL_ASSOC),
112 );
113 }
114
115 /** {@inheritDoc} */
116 public function fetchFirstColumn(): array
117 {
118 if ($this->result === null) {
119 return [];
120 }
121
122 $postgresType = pg_field_type($this->result, 0);
123
124 return array_map(
125 fn ($value) => $this->mapType($postgresType, $value),
126 pg_fetch_all_columns($this->result),
127 );
128 }
129
130 public function rowCount(): int
131 {
132 if ($this->result === null) {
133 return 0;
134 }
135
136 return pg_affected_rows($this->result);
137 }
138
139 public function columnCount(): int
140 {
141 if ($this->result === null) {
142 return 0;
143 }
144
145 return pg_num_fields($this->result);
146 }
147
148 public function free(): void
149 {
150 if ($this->result === null) {
151 return;
152 }
153
154 pg_free_result($this->result);
155 $this->result = null;
156 }
157
158 /** @return array<int, string> */
159 private function fetchNumericColumnTypes(): array
160 {
161 assert($this->result !== null);
162
163 $types = [];
164 $numFields = pg_num_fields($this->result);
165 for ($i = 0; $i < $numFields; ++$i) {
166 $types[$i] = pg_field_type($this->result, $i);
167 }
168
169 return $types;
170 }
171
172 /** @return array<string, string> */
173 private function fetchAssociativeColumnTypes(): array
174 {
175 assert($this->result !== null);
176
177 $types = [];
178 $numFields = pg_num_fields($this->result);
179 for ($i = 0; $i < $numFields; ++$i) {
180 $types[pg_field_name($this->result, $i)] = pg_field_type($this->result, $i);
181 }
182
183 return $types;
184 }
185
186 /**
187 * @param list<string|null> $row
188 * @param array<int, string> $types
189 *
190 * @return list<mixed>
191 */
192 private function mapNumericRow(array $row, array $types): array
193 {
194 assert($this->result !== null);
195
196 return array_map(
197 fn ($value, $field) => $this->mapType($types[$field], $value),
198 $row,
199 array_keys($row),
200 );
201 }
202
203 /**
204 * @param array<string, string|null> $row
205 * @param array<string, string> $types
206 *
207 * @return array<string, mixed>
208 */
209 private function mapAssociativeRow(array $row, array $types): array
210 {
211 assert($this->result !== null);
212
213 $mappedRow = [];
214 foreach ($row as $field => $value) {
215 $mappedRow[$field] = $this->mapType($types[$field], $value);
216 }
217
218 return $mappedRow;
219 }
220
221 private function mapType(string $postgresType, ?string $value): string|int|float|bool|null
222 {
223 if ($value === null) {
224 return null;
225 }
226
227 return match ($postgresType) {
228 'bool' => match ($value) {
229 't' => true,
230 'f' => false,
231 default => throw UnexpectedValue::new($value, $postgresType),
232 },
233 'bytea' => hex2bin(substr($value, 2)),
234 'float4', 'float8' => (float) $value,
235 'int2', 'int4' => (int) $value,
236 'int8' => PHP_INT_SIZE >= 8 ? (int) $value : $value,
237 default => $value,
238 };
239 }
240}
diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Statement.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Statement.php
new file mode 100644
index 0000000..b48ab5d
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Statement.php
@@ -0,0 +1,91 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\PgSQL;
6
7use Doctrine\DBAL\Driver\PgSQL\Exception\UnknownParameter;
8use Doctrine\DBAL\Driver\Statement as StatementInterface;
9use Doctrine\DBAL\ParameterType;
10use PgSql\Connection as PgSqlConnection;
11
12use function assert;
13use function is_resource;
14use function ksort;
15use function pg_escape_bytea;
16use function pg_escape_identifier;
17use function pg_get_result;
18use function pg_last_error;
19use function pg_query;
20use function pg_result_error;
21use function pg_send_execute;
22use function stream_get_contents;
23
24final class Statement implements StatementInterface
25{
26 /** @var array<int, mixed> */
27 private array $parameters = [];
28
29 /** @psalm-var array<int, ParameterType> */
30 private array $parameterTypes = [];
31
32 /** @param array<array-key, int> $parameterMap */
33 public function __construct(
34 private readonly PgSqlConnection $connection,
35 private readonly string $name,
36 private readonly array $parameterMap,
37 ) {
38 }
39
40 public function __destruct()
41 {
42 if (! isset($this->connection)) {
43 return;
44 }
45
46 @pg_query(
47 $this->connection,
48 'DEALLOCATE ' . pg_escape_identifier($this->connection, $this->name),
49 );
50 }
51
52 /** {@inheritDoc} */
53 public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
54 {
55 if (! isset($this->parameterMap[$param])) {
56 throw UnknownParameter::new((string) $param);
57 }
58
59 $this->parameters[$this->parameterMap[$param]] = $value;
60 $this->parameterTypes[$this->parameterMap[$param]] = $type;
61 }
62
63 /** {@inheritDoc} */
64 public function execute(): Result
65 {
66 ksort($this->parameters);
67
68 $escapedParameters = [];
69 foreach ($this->parameters as $parameter => $value) {
70 $escapedParameters[] = match ($this->parameterTypes[$parameter]) {
71 ParameterType::BINARY, ParameterType::LARGE_OBJECT => $value === null
72 ? null
73 : pg_escape_bytea($this->connection, is_resource($value) ? stream_get_contents($value) : $value),
74 default => $value,
75 };
76 }
77
78 if (@pg_send_execute($this->connection, $this->name, $escapedParameters) !== true) {
79 throw new Exception(pg_last_error($this->connection));
80 }
81
82 $result = @pg_get_result($this->connection);
83 assert($result !== false);
84
85 if ((bool) pg_result_error($result)) {
86 throw Exception::fromResult($result);
87 }
88
89 return new Result($result);
90 }
91}
diff --git a/vendor/doctrine/dbal/src/Driver/Result.php b/vendor/doctrine/dbal/src/Driver/Result.php
new file mode 100644
index 0000000..500cb88
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Result.php
@@ -0,0 +1,93 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7/**
8 * Driver-level statement execution result.
9 */
10interface Result
11{
12 /**
13 * Returns the next row of the result as a numeric array or FALSE if there are no more rows.
14 *
15 * @return list<mixed>|false
16 *
17 * @throws Exception
18 */
19 public function fetchNumeric(): array|false;
20
21 /**
22 * Returns the next row of the result as an associative array or FALSE if there are no more rows.
23 *
24 * @return array<string,mixed>|false
25 *
26 * @throws Exception
27 */
28 public function fetchAssociative(): array|false;
29
30 /**
31 * Returns the first value of the next row of the result or FALSE if there are no more rows.
32 *
33 * @throws Exception
34 */
35 public function fetchOne(): mixed;
36
37 /**
38 * Returns an array containing all of the result rows represented as numeric arrays.
39 *
40 * @return list<list<mixed>>
41 *
42 * @throws Exception
43 */
44 public function fetchAllNumeric(): array;
45
46 /**
47 * Returns an array containing all of the result rows represented as associative arrays.
48 *
49 * @return list<array<string,mixed>>
50 *
51 * @throws Exception
52 */
53 public function fetchAllAssociative(): array;
54
55 /**
56 * Returns an array containing the values of the first column of the result.
57 *
58 * @return list<mixed>
59 *
60 * @throws Exception
61 */
62 public function fetchFirstColumn(): array;
63
64 /**
65 * Returns the number of rows affected by the DELETE, INSERT, or UPDATE statement that produced the result.
66 *
67 * If the statement executed a SELECT query or a similar platform-specific SQL (e.g. DESCRIBE, SHOW, etc.),
68 * some database drivers may return the number of rows returned by that query. However, this behaviour
69 * is not guaranteed for all drivers and should not be relied on in portable applications.
70 *
71 * If the number of rows exceeds {@see PHP_INT_MAX}, it might be returned as string if the driver supports it.
72 *
73 * @return int|numeric-string
74 *
75 * @throws Exception
76 */
77 public function rowCount(): int|string;
78
79 /**
80 * Returns the number of columns in the result
81 *
82 * @return int The number of columns in the result. If the columns cannot be counted,
83 * this method must return 0.
84 *
85 * @throws Exception
86 */
87 public function columnCount(): int;
88
89 /**
90 * Discards the non-fetched portion of the result, enabling the originating statement to be executed again.
91 */
92 public function free(): void;
93}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLSrv/Connection.php b/vendor/doctrine/dbal/src/Driver/SQLSrv/Connection.php
new file mode 100644
index 0000000..71050f1
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLSrv/Connection.php
@@ -0,0 +1,108 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLSrv;
6
7use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
8use Doctrine\DBAL\Driver\Exception\NoIdentityValue;
9use Doctrine\DBAL\Driver\SQLSrv\Exception\Error;
10
11use function sqlsrv_begin_transaction;
12use function sqlsrv_commit;
13use function sqlsrv_query;
14use function sqlsrv_rollback;
15use function sqlsrv_rows_affected;
16use function sqlsrv_server_info;
17use function str_replace;
18
19final class Connection implements ConnectionInterface
20{
21 /**
22 * @internal The connection can be only instantiated by its driver.
23 *
24 * @param resource $connection
25 */
26 public function __construct(private readonly mixed $connection)
27 {
28 }
29
30 public function getServerVersion(): string
31 {
32 $serverInfo = sqlsrv_server_info($this->connection);
33
34 return $serverInfo['SQLServerVersion'];
35 }
36
37 public function prepare(string $sql): Statement
38 {
39 return new Statement($this->connection, $sql);
40 }
41
42 public function query(string $sql): Result
43 {
44 return $this->prepare($sql)->execute();
45 }
46
47 public function quote(string $value): string
48 {
49 return "'" . str_replace("'", "''", $value) . "'";
50 }
51
52 public function exec(string $sql): int
53 {
54 $stmt = sqlsrv_query($this->connection, $sql);
55
56 if ($stmt === false) {
57 throw Error::new();
58 }
59
60 $rowsAffected = sqlsrv_rows_affected($stmt);
61
62 if ($rowsAffected === false) {
63 throw Error::new();
64 }
65
66 return $rowsAffected;
67 }
68
69 public function lastInsertId(): int|string
70 {
71 $result = $this->query('SELECT @@IDENTITY');
72
73 $lastInsertId = $result->fetchOne();
74
75 if ($lastInsertId === null) {
76 throw NoIdentityValue::new();
77 }
78
79 return $lastInsertId;
80 }
81
82 public function beginTransaction(): void
83 {
84 if (! sqlsrv_begin_transaction($this->connection)) {
85 throw Error::new();
86 }
87 }
88
89 public function commit(): void
90 {
91 if (! sqlsrv_commit($this->connection)) {
92 throw Error::new();
93 }
94 }
95
96 public function rollBack(): void
97 {
98 if (! sqlsrv_rollback($this->connection)) {
99 throw Error::new();
100 }
101 }
102
103 /** @return resource */
104 public function getNativeConnection()
105 {
106 return $this->connection;
107 }
108}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLSrv/Driver.php b/vendor/doctrine/dbal/src/Driver/SQLSrv/Driver.php
new file mode 100644
index 0000000..c9c2c34
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLSrv/Driver.php
@@ -0,0 +1,73 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLSrv;
6
7use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
8use Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception\PortWithoutHost;
9use Doctrine\DBAL\Driver\SQLSrv\Exception\Error;
10use SensitiveParameter;
11
12use function sqlsrv_configure;
13use function sqlsrv_connect;
14
15/**
16 * Driver for ext/sqlsrv.
17 */
18final class Driver extends AbstractSQLServerDriver
19{
20 /**
21 * {@inheritDoc}
22 */
23 public function connect(
24 #[SensitiveParameter]
25 array $params,
26 ): Connection {
27 $serverName = '';
28
29 if (isset($params['host'])) {
30 $serverName = $params['host'];
31
32 if (isset($params['port'])) {
33 $serverName .= ',' . $params['port'];
34 }
35 } elseif (isset($params['port'])) {
36 throw PortWithoutHost::new();
37 }
38
39 $driverOptions = $params['driverOptions'] ?? [];
40
41 if (isset($params['dbname'])) {
42 $driverOptions['Database'] = $params['dbname'];
43 }
44
45 if (isset($params['charset'])) {
46 $driverOptions['CharacterSet'] = $params['charset'];
47 }
48
49 if (isset($params['user'])) {
50 $driverOptions['UID'] = $params['user'];
51 }
52
53 if (isset($params['password'])) {
54 $driverOptions['PWD'] = $params['password'];
55 }
56
57 if (! isset($driverOptions['ReturnDatesAsStrings'])) {
58 $driverOptions['ReturnDatesAsStrings'] = 1;
59 }
60
61 if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
62 throw Error::new();
63 }
64
65 $connection = sqlsrv_connect($serverName, $driverOptions);
66
67 if ($connection === false) {
68 throw Error::new();
69 }
70
71 return new Connection($connection);
72 }
73}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLSrv/Exception/Error.php b/vendor/doctrine/dbal/src/Driver/SQLSrv/Exception/Error.php
new file mode 100644
index 0000000..f39d5fc
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLSrv/Exception/Error.php
@@ -0,0 +1,44 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLSrv\Exception;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9use function rtrim;
10use function sqlsrv_errors;
11
12use const SQLSRV_ERR_ERRORS;
13
14/**
15 * @internal
16 *
17 * @psalm-immutable
18 */
19final class Error extends AbstractException
20{
21 public static function new(): self
22 {
23 $message = '';
24 $sqlState = null;
25 $code = 0;
26
27 foreach ((array) sqlsrv_errors(SQLSRV_ERR_ERRORS) as $error) {
28 $message .= 'SQLSTATE [' . $error['SQLSTATE'] . ', ' . $error['code'] . ']: ' . $error['message'] . "\n";
29 $sqlState ??= $error['SQLSTATE'];
30
31 if ($code !== 0) {
32 continue;
33 }
34
35 $code = $error['code'];
36 }
37
38 if ($message === '') {
39 $message = 'SQL Server error occurred but no error message was retrieved from driver.';
40 }
41
42 return new self(rtrim($message), $sqlState, $code);
43 }
44}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLSrv/Result.php b/vendor/doctrine/dbal/src/Driver/SQLSrv/Result.php
new file mode 100644
index 0000000..316368f
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLSrv/Result.php
@@ -0,0 +1,104 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLSrv;
6
7use Doctrine\DBAL\Driver\FetchUtils;
8use Doctrine\DBAL\Driver\Result as ResultInterface;
9
10use function sqlsrv_fetch;
11use function sqlsrv_fetch_array;
12use function sqlsrv_num_fields;
13use function sqlsrv_rows_affected;
14
15use const SQLSRV_FETCH_ASSOC;
16use const SQLSRV_FETCH_NUMERIC;
17
18final class Result implements ResultInterface
19{
20 /**
21 * @internal The result can be only instantiated by its driver connection or statement.
22 *
23 * @param resource $statement
24 */
25 public function __construct(private readonly mixed $statement)
26 {
27 }
28
29 public function fetchNumeric(): array|false
30 {
31 return $this->fetch(SQLSRV_FETCH_NUMERIC);
32 }
33
34 public function fetchAssociative(): array|false
35 {
36 return $this->fetch(SQLSRV_FETCH_ASSOC);
37 }
38
39 public function fetchOne(): mixed
40 {
41 return FetchUtils::fetchOne($this);
42 }
43
44 /**
45 * {@inheritDoc}
46 */
47 public function fetchAllNumeric(): array
48 {
49 return FetchUtils::fetchAllNumeric($this);
50 }
51
52 /**
53 * {@inheritDoc}
54 */
55 public function fetchAllAssociative(): array
56 {
57 return FetchUtils::fetchAllAssociative($this);
58 }
59
60 /**
61 * {@inheritDoc}
62 */
63 public function fetchFirstColumn(): array
64 {
65 return FetchUtils::fetchFirstColumn($this);
66 }
67
68 public function rowCount(): int
69 {
70 $count = sqlsrv_rows_affected($this->statement);
71
72 if ($count !== false) {
73 return $count;
74 }
75
76 return 0;
77 }
78
79 public function columnCount(): int
80 {
81 $count = sqlsrv_num_fields($this->statement);
82
83 if ($count !== false) {
84 return $count;
85 }
86
87 return 0;
88 }
89
90 public function free(): void
91 {
92 // emulate it by fetching and discarding rows, similarly to what PDO does in this case
93 // @link http://php.net/manual/en/pdostatement.closecursor.php
94 // @link https://github.com/php/php-src/blob/php-7.0.11/ext/pdo/pdo_stmt.c#L2075
95 // deliberately do not consider multiple result sets, since doctrine/dbal doesn't support them
96 while (sqlsrv_fetch($this->statement)) {
97 }
98 }
99
100 private function fetch(int $fetchType): mixed
101 {
102 return sqlsrv_fetch_array($this->statement, $fetchType) ?? false;
103 }
104}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLSrv/Statement.php b/vendor/doctrine/dbal/src/Driver/SQLSrv/Statement.php
new file mode 100644
index 0000000..dc7827a
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLSrv/Statement.php
@@ -0,0 +1,140 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLSrv;
6
7use Doctrine\DBAL\Driver\Exception;
8use Doctrine\DBAL\Driver\SQLSrv\Exception\Error;
9use Doctrine\DBAL\Driver\Statement as StatementInterface;
10use Doctrine\DBAL\ParameterType;
11
12use function assert;
13use function is_int;
14use function sqlsrv_execute;
15use function SQLSRV_PHPTYPE_STREAM;
16use function SQLSRV_PHPTYPE_STRING;
17use function sqlsrv_prepare;
18use function SQLSRV_SQLTYPE_VARBINARY;
19use function stripos;
20
21use const SQLSRV_ENC_BINARY;
22use const SQLSRV_ENC_CHAR;
23use const SQLSRV_PARAM_IN;
24
25final class Statement implements StatementInterface
26{
27 /**
28 * The SQLSRV statement resource.
29 *
30 * @var resource|null
31 */
32 private $stmt;
33
34 /**
35 * References to the variables bound as statement parameters.
36 *
37 * @var array<int, mixed>
38 */
39 private array $variables = [];
40
41 /**
42 * Bound parameter types.
43 *
44 * @var array<int, ParameterType>
45 */
46 private array $types = [];
47
48 /**
49 * Append to any INSERT query to retrieve the last insert id.
50 */
51 private const LAST_INSERT_ID_SQL = ';SELECT SCOPE_IDENTITY() AS LastInsertId;';
52
53 /**
54 * @internal The statement can be only instantiated by its driver connection.
55 *
56 * @param resource $conn
57 */
58 public function __construct(
59 private readonly mixed $conn,
60 private string $sql,
61 ) {
62 if (stripos($sql, 'INSERT INTO ') !== 0) {
63 return;
64 }
65
66 $this->sql .= self::LAST_INSERT_ID_SQL;
67 }
68
69 public function bindValue(int|string $param, mixed $value, ParameterType $type): void
70 {
71 assert(is_int($param));
72
73 $this->variables[$param] = $value;
74 $this->types[$param] = $type;
75 }
76
77 public function execute(): Result
78 {
79 $this->stmt ??= $this->prepare();
80
81 if (! sqlsrv_execute($this->stmt)) {
82 throw Error::new();
83 }
84
85 return new Result($this->stmt);
86 }
87
88 /**
89 * Prepares SQL Server statement resource
90 *
91 * @return resource
92 *
93 * @throws Exception
94 */
95 private function prepare()
96 {
97 $params = [];
98
99 foreach ($this->variables as $column => &$variable) {
100 switch ($this->types[$column]) {
101 case ParameterType::LARGE_OBJECT:
102 $params[$column - 1] = [
103 &$variable,
104 SQLSRV_PARAM_IN,
105 SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY),
106 SQLSRV_SQLTYPE_VARBINARY('max'),
107 ];
108 break;
109
110 case ParameterType::BINARY:
111 $params[$column - 1] = [
112 &$variable,
113 SQLSRV_PARAM_IN,
114 SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY),
115 ];
116 break;
117
118 case ParameterType::ASCII:
119 $params[$column - 1] = [
120 &$variable,
121 SQLSRV_PARAM_IN,
122 SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR),
123 ];
124 break;
125
126 default:
127 $params[$column - 1] =& $variable;
128 break;
129 }
130 }
131
132 $stmt = sqlsrv_prepare($this->conn, $this->sql, $params);
133
134 if ($stmt === false) {
135 throw Error::new();
136 }
137
138 return $stmt;
139 }
140}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Connection.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Connection.php
new file mode 100644
index 0000000..1e9af93
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Connection.php
@@ -0,0 +1,109 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLite3;
6
7use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
8use Doctrine\DBAL\Driver\Exception\NoIdentityValue;
9use SQLite3;
10
11use function assert;
12use function sprintf;
13
14final class Connection implements ConnectionInterface
15{
16 /** @internal The connection can be only instantiated by its driver. */
17 public function __construct(private readonly SQLite3 $connection)
18 {
19 }
20
21 public function prepare(string $sql): Statement
22 {
23 try {
24 $statement = $this->connection->prepare($sql);
25 } catch (\Exception $e) {
26 throw Exception::new($e);
27 }
28
29 assert($statement !== false);
30
31 return new Statement($this->connection, $statement);
32 }
33
34 public function query(string $sql): Result
35 {
36 try {
37 $result = $this->connection->query($sql);
38 } catch (\Exception $e) {
39 throw Exception::new($e);
40 }
41
42 assert($result !== false);
43
44 return new Result($result, $this->connection->changes());
45 }
46
47 public function quote(string $value): string
48 {
49 return sprintf('\'%s\'', SQLite3::escapeString($value));
50 }
51
52 public function exec(string $sql): int
53 {
54 try {
55 $this->connection->exec($sql);
56 } catch (\Exception $e) {
57 throw Exception::new($e);
58 }
59
60 return $this->connection->changes();
61 }
62
63 public function lastInsertId(): int
64 {
65 $value = $this->connection->lastInsertRowID();
66 if ($value === 0) {
67 throw NoIdentityValue::new();
68 }
69
70 return $value;
71 }
72
73 public function beginTransaction(): void
74 {
75 try {
76 $this->connection->exec('BEGIN');
77 } catch (\Exception $e) {
78 throw Exception::new($e);
79 }
80 }
81
82 public function commit(): void
83 {
84 try {
85 $this->connection->exec('COMMIT');
86 } catch (\Exception $e) {
87 throw Exception::new($e);
88 }
89 }
90
91 public function rollBack(): void
92 {
93 try {
94 $this->connection->exec('ROLLBACK');
95 } catch (\Exception $e) {
96 throw Exception::new($e);
97 }
98 }
99
100 public function getNativeConnection(): SQLite3
101 {
102 return $this->connection;
103 }
104
105 public function getServerVersion(): string
106 {
107 return SQLite3::version()['versionString'];
108 }
109}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Driver.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Driver.php
new file mode 100644
index 0000000..e6996d3
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Driver.php
@@ -0,0 +1,48 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLite3;
6
7use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
8use SensitiveParameter;
9use SQLite3;
10
11final class Driver extends AbstractSQLiteDriver
12{
13 /**
14 * {@inheritDoc}
15 */
16 public function connect(
17 #[SensitiveParameter]
18 array $params,
19 ): Connection {
20 $isMemory = $params['memory'] ?? false;
21
22 if (isset($params['path'])) {
23 if ($isMemory) {
24 throw new Exception(
25 'Invalid connection settings: specifying both parameters "path" and "memory" is ambiguous.',
26 );
27 }
28
29 $filename = $params['path'];
30 } elseif ($isMemory) {
31 $filename = ':memory:';
32 } else {
33 throw new Exception(
34 'Invalid connection settings: specify either the "path" or the "memory" parameter for SQLite3.',
35 );
36 }
37
38 try {
39 $connection = new SQLite3($filename);
40 } catch (\Exception $e) {
41 throw Exception::new($e);
42 }
43
44 $connection->enableExceptions(true);
45
46 return new Connection($connection);
47 }
48}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Exception.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Exception.php
new file mode 100644
index 0000000..d423004
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Exception.php
@@ -0,0 +1,20 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLite3;
6
7use Doctrine\DBAL\Driver\AbstractException;
8
9/**
10 * @internal
11 *
12 * @psalm-immutable
13 */
14final class Exception extends AbstractException
15{
16 public static function new(\Exception $exception): self
17 {
18 return new self($exception->getMessage(), null, (int) $exception->getCode(), $exception);
19 }
20}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Result.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Result.php
new file mode 100644
index 0000000..61b42d3
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Result.php
@@ -0,0 +1,88 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLite3;
6
7use Doctrine\DBAL\Driver\FetchUtils;
8use Doctrine\DBAL\Driver\Result as ResultInterface;
9use SQLite3Result;
10
11use const SQLITE3_ASSOC;
12use const SQLITE3_NUM;
13
14final class Result implements ResultInterface
15{
16 private ?SQLite3Result $result;
17
18 /** @internal The result can be only instantiated by its driver connection or statement. */
19 public function __construct(SQLite3Result $result, private readonly int $changes)
20 {
21 $this->result = $result;
22 }
23
24 public function fetchNumeric(): array|false
25 {
26 if ($this->result === null) {
27 return false;
28 }
29
30 return $this->result->fetchArray(SQLITE3_NUM);
31 }
32
33 public function fetchAssociative(): array|false
34 {
35 if ($this->result === null) {
36 return false;
37 }
38
39 return $this->result->fetchArray(SQLITE3_ASSOC);
40 }
41
42 public function fetchOne(): mixed
43 {
44 return FetchUtils::fetchOne($this);
45 }
46
47 /** @inheritDoc */
48 public function fetchAllNumeric(): array
49 {
50 return FetchUtils::fetchAllNumeric($this);
51 }
52
53 /** @inheritDoc */
54 public function fetchAllAssociative(): array
55 {
56 return FetchUtils::fetchAllAssociative($this);
57 }
58
59 /** @inheritDoc */
60 public function fetchFirstColumn(): array
61 {
62 return FetchUtils::fetchFirstColumn($this);
63 }
64
65 public function rowCount(): int
66 {
67 return $this->changes;
68 }
69
70 public function columnCount(): int
71 {
72 if ($this->result === null) {
73 return 0;
74 }
75
76 return $this->result->numColumns();
77 }
78
79 public function free(): void
80 {
81 if ($this->result === null) {
82 return;
83 }
84
85 $this->result->finalize();
86 $this->result = null;
87 }
88}
diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Statement.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Statement.php
new file mode 100644
index 0000000..fe22e1d
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Statement.php
@@ -0,0 +1,61 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver\SQLite3;
6
7use Doctrine\DBAL\Driver\Statement as StatementInterface;
8use Doctrine\DBAL\ParameterType;
9use SQLite3;
10use SQLite3Stmt;
11
12use function assert;
13
14use const SQLITE3_BLOB;
15use const SQLITE3_INTEGER;
16use const SQLITE3_NULL;
17use const SQLITE3_TEXT;
18
19final class Statement implements StatementInterface
20{
21 private const TYPE_BLOB = SQLITE3_BLOB;
22 private const TYPE_INTEGER = SQLITE3_INTEGER;
23 private const TYPE_NULL = SQLITE3_NULL;
24 private const TYPE_TEXT = SQLITE3_TEXT;
25
26 /** @internal The statement can be only instantiated by its driver connection. */
27 public function __construct(
28 private readonly SQLite3 $connection,
29 private readonly SQLite3Stmt $statement,
30 ) {
31 }
32
33 public function bindValue(int|string $param, mixed $value, ParameterType $type): void
34 {
35 $this->statement->bindValue($param, $value, $this->convertParamType($type));
36 }
37
38 public function execute(): Result
39 {
40 try {
41 $result = $this->statement->execute();
42 } catch (\Exception $e) {
43 throw Exception::new($e);
44 }
45
46 assert($result !== false);
47
48 return new Result($result, $this->connection->changes());
49 }
50
51 /** @psalm-return self::TYPE_* */
52 private function convertParamType(ParameterType $type): int
53 {
54 return match ($type) {
55 ParameterType::NULL => self::TYPE_NULL,
56 ParameterType::INTEGER, ParameterType::BOOLEAN => self::TYPE_INTEGER,
57 ParameterType::STRING, ParameterType::ASCII => self::TYPE_TEXT,
58 ParameterType::BINARY, ParameterType::LARGE_OBJECT => self::TYPE_BLOB,
59 };
60 }
61}
diff --git a/vendor/doctrine/dbal/src/Driver/Statement.php b/vendor/doctrine/dbal/src/Driver/Statement.php
new file mode 100644
index 0000000..5f91b49
--- /dev/null
+++ b/vendor/doctrine/dbal/src/Driver/Statement.php
@@ -0,0 +1,39 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Doctrine\DBAL\Driver;
6
7use Doctrine\DBAL\ParameterType;
8
9/**
10 * Driver-level statement
11 */
12interface Statement
13{
14 /**
15 * Binds a value to a corresponding named (not supported by mysqli driver, see comment below) or positional
16 * placeholder in the SQL statement that was used to prepare the statement.
17 *
18 * As mentioned above, the named parameters are not natively supported by the mysqli driver, use executeQuery(),
19 * fetchAll(), fetchArray(), fetchColumn(), fetchAssoc() methods to have the named parameter emulated by doctrine.
20 *
21 * @param int|string $param Parameter identifier. For a prepared statement using named placeholders,
22 * this will be a parameter name of the form :name. For a prepared statement
23 * using question mark placeholders, this will be the 1-indexed position
24 * of the parameter.
25 * @param mixed $value The value to bind to the parameter.
26 * @param ParameterType $type Explicit data type for the parameter using the {@see ParameterType}
27 * constants.
28 *
29 * @throws Exception
30 */
31 public function bindValue(int|string $param, mixed $value, ParameterType $type): void;
32
33 /**
34 * Executes a prepared statement
35 *
36 * @throws Exception
37 */
38 public function execute(): Result;
39}