PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.35.1
MailPoet – Newsletters, Email Marketing, and Automation v5.35.1
5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor-prefixed / doctrine / dbal / src / Connection.php
mailpoet / vendor-prefixed / doctrine / dbal / src Last commit date
ArrayParameters 2 years ago Cache 9 months ago Driver 9 months ago Event 2 years ago Exception 9 months ago Id 2 years ago Logging 2 years ago Platforms 9 months ago Portability 2 years ago Query 2 years ago SQL 9 months ago Schema 8 months ago Types 9 months ago ArrayParameterType.php 2 years ago ColumnCase.php 2 years ago Configuration.php 9 months ago Connection.php 9 months ago ConnectionException.php 2 years ago Driver.php 2 years ago DriverManager.php 2 years ago Events.php 2 years ago Exception.php 2 years ago ExpandArrayParameters.php 2 years ago FetchMode.php 2 years ago LockMode.php 2 years ago ParameterType.php 2 years ago Query.php 2 years ago Result.php 2 years ago Statement.php 2 years ago TransactionIsolationLevel.php 2 years ago VersionAwarePlatformDriver.php 2 years ago index.php 2 years ago
Connection.php
870 lines
1 <?php
2 namespace MailPoetVendor\Doctrine\DBAL;
3 if (!defined('ABSPATH')) exit;
4 use Closure;
5 use MailPoetVendor\Doctrine\Common\EventManager;
6 use MailPoetVendor\Doctrine\DBAL\Cache\ArrayResult;
7 use MailPoetVendor\Doctrine\DBAL\Cache\CacheException;
8 use MailPoetVendor\Doctrine\DBAL\Cache\QueryCacheProfile;
9 use MailPoetVendor\Doctrine\DBAL\Driver\API\ExceptionConverter;
10 use MailPoetVendor\Doctrine\DBAL\Driver\Connection as DriverConnection;
11 use MailPoetVendor\Doctrine\DBAL\Driver\Exception as TheDriverException;
12 use MailPoetVendor\Doctrine\DBAL\Driver\ServerInfoAwareConnection;
13 use MailPoetVendor\Doctrine\DBAL\Driver\Statement as DriverStatement;
14 use MailPoetVendor\Doctrine\DBAL\Event\TransactionBeginEventArgs;
15 use MailPoetVendor\Doctrine\DBAL\Event\TransactionCommitEventArgs;
16 use MailPoetVendor\Doctrine\DBAL\Event\TransactionRollBackEventArgs;
17 use MailPoetVendor\Doctrine\DBAL\Exception\ConnectionLost;
18 use MailPoetVendor\Doctrine\DBAL\Exception\DeadlockException;
19 use MailPoetVendor\Doctrine\DBAL\Exception\DriverException;
20 use MailPoetVendor\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
21 use MailPoetVendor\Doctrine\DBAL\Exception\InvalidArgumentException;
22 use MailPoetVendor\Doctrine\DBAL\Exception\TransactionRolledBack;
23 use MailPoetVendor\Doctrine\DBAL\Exception\UniqueConstraintViolationException;
24 use MailPoetVendor\Doctrine\DBAL\Platforms\AbstractPlatform;
25 use MailPoetVendor\Doctrine\DBAL\Query\Expression\ExpressionBuilder;
26 use MailPoetVendor\Doctrine\DBAL\Query\QueryBuilder;
27 use MailPoetVendor\Doctrine\DBAL\Schema\AbstractSchemaManager;
28 use MailPoetVendor\Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
29 use MailPoetVendor\Doctrine\DBAL\Schema\LegacySchemaManagerFactory;
30 use MailPoetVendor\Doctrine\DBAL\Schema\SchemaManagerFactory;
31 use MailPoetVendor\Doctrine\DBAL\SQL\Parser;
32 use MailPoetVendor\Doctrine\DBAL\Types\Type;
33 use MailPoetVendor\Doctrine\Deprecations\Deprecation;
34 use LogicException;
35 use MailPoetVendor\SensitiveParameter;
36 use Throwable;
37 use Traversable;
38 use function array_key_exists;
39 use function assert;
40 use function count;
41 use function get_class;
42 use function implode;
43 use function is_array;
44 use function is_int;
45 use function is_string;
46 use function key;
47 use function method_exists;
48 use function sprintf;
49 class Connection
50 {
51 public const PARAM_INT_ARRAY = ArrayParameterType::INTEGER;
52 public const PARAM_STR_ARRAY = ArrayParameterType::STRING;
53 public const PARAM_ASCII_STR_ARRAY = ArrayParameterType::ASCII;
54 public const ARRAY_PARAM_OFFSET = 100;
55 protected $_conn;
56 protected $_config;
57 protected $_eventManager;
58 protected $_expr;
59 private bool $autoCommit = \true;
60 private int $transactionNestingLevel = 0;
61 private $transactionIsolationLevel;
62 private bool $nestTransactionsWithSavepoints = \false;
63 private array $params;
64 private ?AbstractPlatform $platform = null;
65 private ?ExceptionConverter $exceptionConverter = null;
66 private ?Parser $parser = null;
67 protected $_schemaManager;
68 protected $_driver;
69 private bool $isRollbackOnly = \false;
70 private SchemaManagerFactory $schemaManagerFactory;
71 public function __construct( array $params, Driver $driver, ?Configuration $config = null, ?EventManager $eventManager = null)
72 {
73 $this->_driver = $driver;
74 $this->params = $params;
75 // Create default config and event manager if none given
76 $config ??= new Configuration();
77 $eventManager ??= new EventManager();
78 $this->_config = $config;
79 $this->_eventManager = $eventManager;
80 if (isset($params['platform'])) {
81 if (!$params['platform'] instanceof Platforms\AbstractPlatform) {
82 throw Exception::invalidPlatformType($params['platform']);
83 }
84 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5699', 'The "platform" connection parameter is deprecated.' . ' Use a driver middleware that would instantiate the platform instead.');
85 $this->platform = $params['platform'];
86 $this->platform->setEventManager($this->_eventManager);
87 $this->platform->setDisableTypeComments($config->getDisableTypeComments());
88 }
89 $this->_expr = $this->createExpressionBuilder();
90 $this->autoCommit = $config->getAutoCommit();
91 $schemaManagerFactory = $config->getSchemaManagerFactory();
92 if ($schemaManagerFactory === null) {
93 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/5812', 'Not configuring a schema manager factory is deprecated.' . ' Use %s which is going to be the default in DBAL 4.', DefaultSchemaManagerFactory::class);
94 $schemaManagerFactory = new LegacySchemaManagerFactory();
95 }
96 $this->schemaManagerFactory = $schemaManagerFactory;
97 }
98 public function getParams()
99 {
100 return $this->params;
101 }
102 public function getDatabase()
103 {
104 $platform = $this->getDatabasePlatform();
105 $query = $platform->getDummySelectSQL($platform->getCurrentDatabaseExpression());
106 $database = $this->fetchOne($query);
107 assert(is_string($database) || $database === null);
108 return $database;
109 }
110 public function getDriver()
111 {
112 return $this->_driver;
113 }
114 public function getConfiguration()
115 {
116 return $this->_config;
117 }
118 public function getEventManager()
119 {
120 Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/5784', '%s is deprecated.', __METHOD__);
121 return $this->_eventManager;
122 }
123 public function getDatabasePlatform()
124 {
125 if ($this->platform === null) {
126 $this->platform = $this->detectDatabasePlatform();
127 $this->platform->setEventManager($this->_eventManager);
128 $this->platform->setDisableTypeComments($this->_config->getDisableTypeComments());
129 }
130 return $this->platform;
131 }
132 public function createExpressionBuilder() : ExpressionBuilder
133 {
134 return new ExpressionBuilder($this);
135 }
136 public function getExpressionBuilder()
137 {
138 Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/4515', 'Connection::getExpressionBuilder() is deprecated,' . ' use Connection::createExpressionBuilder() instead.');
139 return $this->_expr;
140 }
141 public function connect()
142 {
143 Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/4966', 'Public access to Connection::connect() is deprecated.');
144 if ($this->_conn !== null) {
145 return \false;
146 }
147 try {
148 $this->_conn = $this->_driver->connect($this->params);
149 } catch (Driver\Exception $e) {
150 throw $this->convertException($e);
151 }
152 if ($this->autoCommit === \false) {
153 $this->beginTransaction();
154 }
155 if ($this->_eventManager->hasListeners(Events::postConnect)) {
156 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/5784', 'Subscribing to %s events is deprecated. Implement a middleware instead.', Events::postConnect);
157 $eventArgs = new Event\ConnectionEventArgs($this);
158 $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
159 }
160 return \true;
161 }
162 private function detectDatabasePlatform() : AbstractPlatform
163 {
164 $version = $this->getDatabasePlatformVersion();
165 if ($version !== null) {
166 assert($this->_driver instanceof VersionAwarePlatformDriver);
167 return $this->_driver->createDatabasePlatformForVersion($version);
168 }
169 return $this->_driver->getDatabasePlatform();
170 }
171 private function getDatabasePlatformVersion()
172 {
173 // Driver does not support version specific platforms.
174 if (!$this->_driver instanceof VersionAwarePlatformDriver) {
175 return null;
176 }
177 // Explicit platform version requested (supersedes auto-detection).
178 if (isset($this->params['serverVersion'])) {
179 return $this->params['serverVersion'];
180 }
181 if (isset($this->params['primary']) && isset($this->params['primary']['serverVersion'])) {
182 return $this->params['primary']['serverVersion'];
183 }
184 // If not connected, we need to connect now to determine the platform version.
185 if ($this->_conn === null) {
186 try {
187 $this->connect();
188 } catch (Exception $originalException) {
189 if (!isset($this->params['dbname'])) {
190 throw $originalException;
191 }
192 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5707', 'Relying on a fallback connection used to determine the database platform while connecting' . ' to a non-existing database is deprecated. Either use an existing database name in' . ' connection parameters or omit the database name if the platform' . ' and the server configuration allow that.');
193 // The database to connect to might not yet exist.
194 // Retry detection without database name connection parameter.
195 $params = $this->params;
196 unset($this->params['dbname']);
197 try {
198 $this->connect();
199 } catch (Exception $fallbackException) {
200 // Either the platform does not support database-less connections
201 // or something else went wrong.
202 throw $originalException;
203 } finally {
204 $this->params = $params;
205 }
206 $serverVersion = $this->getServerVersion();
207 // Close "temporary" connection to allow connecting to the real database again.
208 $this->close();
209 return $serverVersion;
210 }
211 }
212 return $this->getServerVersion();
213 }
214 private function getServerVersion()
215 {
216 $connection = $this->getWrappedConnection();
217 // Automatic platform version detection.
218 if ($connection instanceof ServerInfoAwareConnection) {
219 try {
220 return $connection->getServerVersion();
221 } catch (Driver\Exception $e) {
222 throw $this->convertException($e);
223 }
224 }
225 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4750', 'Not implementing the ServerInfoAwareConnection interface in %s is deprecated', get_class($connection));
226 // Unable to detect platform version.
227 return null;
228 }
229 public function isAutoCommit()
230 {
231 return $this->autoCommit === \true;
232 }
233 public function setAutoCommit($autoCommit)
234 {
235 $autoCommit = (bool) $autoCommit;
236 // Mode not changed, no-op.
237 if ($autoCommit === $this->autoCommit) {
238 return;
239 }
240 $this->autoCommit = $autoCommit;
241 // Commit all currently active transactions if any when switching auto-commit mode.
242 if ($this->_conn === null || $this->transactionNestingLevel === 0) {
243 return;
244 }
245 $this->commitAll();
246 }
247 public function fetchAssociative(string $query, array $params = [], array $types = [])
248 {
249 return $this->executeQuery($query, $params, $types)->fetchAssociative();
250 }
251 public function fetchNumeric(string $query, array $params = [], array $types = [])
252 {
253 return $this->executeQuery($query, $params, $types)->fetchNumeric();
254 }
255 public function fetchOne(string $query, array $params = [], array $types = [])
256 {
257 return $this->executeQuery($query, $params, $types)->fetchOne();
258 }
259 public function isConnected()
260 {
261 return $this->_conn !== null;
262 }
263 public function isTransactionActive()
264 {
265 return $this->transactionNestingLevel > 0;
266 }
267 private function addCriteriaCondition(array $criteria, array &$columns, array &$values, array &$conditions) : void
268 {
269 $platform = $this->getDatabasePlatform();
270 foreach ($criteria as $columnName => $value) {
271 if ($value === null) {
272 $conditions[] = $platform->getIsNullExpression($columnName);
273 continue;
274 }
275 $columns[] = $columnName;
276 $values[] = $value;
277 $conditions[] = $columnName . ' = ?';
278 }
279 }
280 public function delete($table, array $criteria, array $types = [])
281 {
282 if (count($criteria) === 0) {
283 throw InvalidArgumentException::fromEmptyCriteria();
284 }
285 $columns = $values = $conditions = [];
286 $this->addCriteriaCondition($criteria, $columns, $values, $conditions);
287 return $this->executeStatement('DELETE FROM ' . $table . ' WHERE ' . implode(' AND ', $conditions), $values, is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types);
288 }
289 public function close()
290 {
291 $this->_conn = null;
292 $this->transactionNestingLevel = 0;
293 }
294 public function setTransactionIsolation($level)
295 {
296 $this->transactionIsolationLevel = $level;
297 return $this->executeStatement($this->getDatabasePlatform()->getSetTransactionIsolationSQL($level));
298 }
299 public function getTransactionIsolation()
300 {
301 return $this->transactionIsolationLevel ??= $this->getDatabasePlatform()->getDefaultTransactionIsolationLevel();
302 }
303 public function update($table, array $data, array $criteria, array $types = [])
304 {
305 $columns = $values = $conditions = $set = [];
306 foreach ($data as $columnName => $value) {
307 $columns[] = $columnName;
308 $values[] = $value;
309 $set[] = $columnName . ' = ?';
310 }
311 $this->addCriteriaCondition($criteria, $columns, $values, $conditions);
312 if (is_string(key($types))) {
313 $types = $this->extractTypeValues($columns, $types);
314 }
315 $sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $set) . ' WHERE ' . implode(' AND ', $conditions);
316 return $this->executeStatement($sql, $values, $types);
317 }
318 public function insert($table, array $data, array $types = [])
319 {
320 if (count($data) === 0) {
321 return $this->executeStatement('INSERT INTO ' . $table . ' () VALUES ()');
322 }
323 $columns = [];
324 $values = [];
325 $set = [];
326 foreach ($data as $columnName => $value) {
327 $columns[] = $columnName;
328 $values[] = $value;
329 $set[] = '?';
330 }
331 return $this->executeStatement('INSERT INTO ' . $table . ' (' . implode(', ', $columns) . ')' . ' VALUES (' . implode(', ', $set) . ')', $values, is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types);
332 }
333 private function extractTypeValues(array $columnList, array $types) : array
334 {
335 $typeValues = [];
336 foreach ($columnList as $columnName) {
337 $typeValues[] = $types[$columnName] ?? ParameterType::STRING;
338 }
339 return $typeValues;
340 }
341 public function quoteIdentifier($str)
342 {
343 return $this->getDatabasePlatform()->quoteIdentifier($str);
344 }
345 public function quote($value, $type = ParameterType::STRING)
346 {
347 $connection = $this->getWrappedConnection();
348 [$value, $bindingType] = $this->getBindingInfo($value, $type);
349 return $connection->quote($value, $bindingType);
350 }
351 public function fetchAllNumeric(string $query, array $params = [], array $types = []) : array
352 {
353 return $this->executeQuery($query, $params, $types)->fetchAllNumeric();
354 }
355 public function fetchAllAssociative(string $query, array $params = [], array $types = []) : array
356 {
357 return $this->executeQuery($query, $params, $types)->fetchAllAssociative();
358 }
359 public function fetchAllKeyValue(string $query, array $params = [], array $types = []) : array
360 {
361 return $this->executeQuery($query, $params, $types)->fetchAllKeyValue();
362 }
363 public function fetchAllAssociativeIndexed(string $query, array $params = [], array $types = []) : array
364 {
365 return $this->executeQuery($query, $params, $types)->fetchAllAssociativeIndexed();
366 }
367 public function fetchFirstColumn(string $query, array $params = [], array $types = []) : array
368 {
369 return $this->executeQuery($query, $params, $types)->fetchFirstColumn();
370 }
371 public function iterateNumeric(string $query, array $params = [], array $types = []) : Traversable
372 {
373 return $this->executeQuery($query, $params, $types)->iterateNumeric();
374 }
375 public function iterateAssociative(string $query, array $params = [], array $types = []) : Traversable
376 {
377 return $this->executeQuery($query, $params, $types)->iterateAssociative();
378 }
379 public function iterateKeyValue(string $query, array $params = [], array $types = []) : Traversable
380 {
381 return $this->executeQuery($query, $params, $types)->iterateKeyValue();
382 }
383 public function iterateAssociativeIndexed(string $query, array $params = [], array $types = []) : Traversable
384 {
385 return $this->executeQuery($query, $params, $types)->iterateAssociativeIndexed();
386 }
387 public function iterateColumn(string $query, array $params = [], array $types = []) : Traversable
388 {
389 return $this->executeQuery($query, $params, $types)->iterateColumn();
390 }
391 public function prepare(string $sql) : Statement
392 {
393 $connection = $this->getWrappedConnection();
394 try {
395 $statement = $connection->prepare($sql);
396 } catch (Driver\Exception $e) {
397 throw $this->convertExceptionDuringQuery($e, $sql);
398 }
399 return new Statement($this, $statement, $sql);
400 }
401 public function executeQuery(string $sql, array $params = [], $types = [], ?QueryCacheProfile $qcp = null) : Result
402 {
403 if ($qcp !== null) {
404 return $this->executeCacheQuery($sql, $params, $types, $qcp);
405 }
406 $connection = $this->getWrappedConnection();
407 $logger = $this->_config->getSQLLogger();
408 if ($logger !== null) {
409 $logger->startQuery($sql, $params, $types);
410 }
411 try {
412 if (count($params) > 0) {
413 if ($this->needsArrayParameterConversion($params, $types)) {
414 [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types);
415 }
416 $stmt = $connection->prepare($sql);
417 $this->bindParameters($stmt, $params, $types);
418 $result = $stmt->execute();
419 } else {
420 $result = $connection->query($sql);
421 }
422 return new Result($result, $this);
423 } catch (Driver\Exception $e) {
424 throw $this->convertExceptionDuringQuery($e, $sql, $params, $types);
425 } finally {
426 if ($logger !== null) {
427 $logger->stopQuery();
428 }
429 }
430 }
431 public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp) : Result
432 {
433 $resultCache = $qcp->getResultCache() ?? $this->_config->getResultCache();
434 if ($resultCache === null) {
435 throw CacheException::noResultDriverConfigured();
436 }
437 $connectionParams = $this->params;
438 unset($connectionParams['platform'], $connectionParams['password'], $connectionParams['url']);
439 [$cacheKey, $realKey] = $qcp->generateCacheKeys($sql, $params, $types, $connectionParams);
440 $item = $resultCache->getItem($cacheKey);
441 if ($item->isHit()) {
442 $value = $item->get();
443 if (!is_array($value)) {
444 $value = [];
445 }
446 if (isset($value[$realKey])) {
447 return new Result(new ArrayResult($value[$realKey]), $this);
448 }
449 } else {
450 $value = [];
451 }
452 $data = $this->fetchAllAssociative($sql, $params, $types);
453 $value[$realKey] = $data;
454 $item->set($value);
455 $lifetime = $qcp->getLifetime();
456 if ($lifetime > 0) {
457 $item->expiresAfter($lifetime);
458 }
459 $resultCache->save($item);
460 return new Result(new ArrayResult($data), $this);
461 }
462 public function executeStatement($sql, array $params = [], array $types = [])
463 {
464 $connection = $this->getWrappedConnection();
465 $logger = $this->_config->getSQLLogger();
466 if ($logger !== null) {
467 $logger->startQuery($sql, $params, $types);
468 }
469 try {
470 if (count($params) > 0) {
471 if ($this->needsArrayParameterConversion($params, $types)) {
472 [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types);
473 }
474 $stmt = $connection->prepare($sql);
475 $this->bindParameters($stmt, $params, $types);
476 return $stmt->execute()->rowCount();
477 }
478 return $connection->exec($sql);
479 } catch (Driver\Exception $e) {
480 throw $this->convertExceptionDuringQuery($e, $sql, $params, $types);
481 } finally {
482 if ($logger !== null) {
483 $logger->stopQuery();
484 }
485 }
486 }
487 public function getTransactionNestingLevel()
488 {
489 return $this->transactionNestingLevel;
490 }
491 public function lastInsertId($name = null)
492 {
493 if ($name !== null) {
494 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/4687', 'The usage of Connection::lastInsertId() with a sequence name is deprecated.');
495 }
496 try {
497 return $this->getWrappedConnection()->lastInsertId($name);
498 } catch (Driver\Exception $e) {
499 throw $this->convertException($e);
500 }
501 }
502 public function transactional(Closure $func)
503 {
504 $this->beginTransaction();
505 $successful = \false;
506 try {
507 $res = $func($this);
508 $successful = \true;
509 } finally {
510 if (!$successful) {
511 $this->rollBack();
512 }
513 }
514 $shouldRollback = \true;
515 try {
516 $this->commit();
517 $shouldRollback = \false;
518 } catch (TheDriverException $t) {
519 $convertedException = $this->handleDriverException($t, null);
520 $shouldRollback = !($convertedException instanceof TransactionRolledBack || $convertedException instanceof UniqueConstraintViolationException || $convertedException instanceof ForeignKeyConstraintViolationException || $convertedException instanceof DeadlockException);
521 throw $t;
522 } finally {
523 if ($shouldRollback) {
524 $this->rollBack();
525 }
526 }
527 return $res;
528 }
529 public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints)
530 {
531 if (!$nestTransactionsWithSavepoints) {
532 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5383', <<<'DEPRECATION'
533 Nesting transactions without enabling savepoints is deprecated.
534 Call %s::setNestTransactionsWithSavepoints(true) to enable savepoints.
535 DEPRECATION
536 , self::class);
537 }
538 if ($this->transactionNestingLevel > 0) {
539 throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction();
540 }
541 $this->nestTransactionsWithSavepoints = (bool) $nestTransactionsWithSavepoints;
542 }
543 public function getNestTransactionsWithSavepoints()
544 {
545 return $this->nestTransactionsWithSavepoints;
546 }
547 protected function _getNestedTransactionSavePointName()
548 {
549 return 'DOCTRINE_' . $this->transactionNestingLevel;
550 }
551 public function beginTransaction()
552 {
553 $connection = $this->getWrappedConnection();
554 ++$this->transactionNestingLevel;
555 $logger = $this->_config->getSQLLogger();
556 if ($this->transactionNestingLevel === 1) {
557 if ($logger !== null) {
558 $logger->startQuery('"START TRANSACTION"');
559 }
560 $connection->beginTransaction();
561 if ($logger !== null) {
562 $logger->stopQuery();
563 }
564 } elseif ($this->nestTransactionsWithSavepoints) {
565 if ($logger !== null) {
566 $logger->startQuery('"SAVEPOINT"');
567 }
568 $this->createSavepoint($this->_getNestedTransactionSavePointName());
569 if ($logger !== null) {
570 $logger->stopQuery();
571 }
572 } else {
573 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5383', <<<'DEPRECATION'
574 Nesting transactions without enabling savepoints is deprecated.
575 Call %s::setNestTransactionsWithSavepoints(true) to enable savepoints.
576 DEPRECATION
577 , self::class);
578 }
579 $eventManager = $this->getEventManager();
580 if ($eventManager->hasListeners(Events::onTransactionBegin)) {
581 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/5784', 'Subscribing to %s events is deprecated.', Events::onTransactionBegin);
582 $eventManager->dispatchEvent(Events::onTransactionBegin, new TransactionBeginEventArgs($this));
583 }
584 return \true;
585 }
586 public function commit()
587 {
588 if ($this->transactionNestingLevel === 0) {
589 throw ConnectionException::noActiveTransaction();
590 }
591 if ($this->isRollbackOnly) {
592 throw ConnectionException::commitFailedRollbackOnly();
593 }
594 $result = \true;
595 $connection = $this->getWrappedConnection();
596 try {
597 if ($this->transactionNestingLevel === 1) {
598 $result = $this->doCommit($connection);
599 } elseif ($this->nestTransactionsWithSavepoints) {
600 $this->releaseSavepoint($this->_getNestedTransactionSavePointName());
601 }
602 } finally {
603 $this->updateTransactionStateAfterCommit();
604 }
605 return $result;
606 }
607 private function updateTransactionStateAfterCommit() : void
608 {
609 --$this->transactionNestingLevel;
610 $eventManager = $this->getEventManager();
611 if ($eventManager->hasListeners(Events::onTransactionCommit)) {
612 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/5784', 'Subscribing to %s events is deprecated.', Events::onTransactionCommit);
613 $eventManager->dispatchEvent(Events::onTransactionCommit, new TransactionCommitEventArgs($this));
614 }
615 if ($this->autoCommit !== \false || $this->transactionNestingLevel !== 0) {
616 return;
617 }
618 $this->beginTransaction();
619 }
620 private function doCommit(DriverConnection $connection)
621 {
622 $logger = $this->_config->getSQLLogger();
623 if ($logger !== null) {
624 $logger->startQuery('"COMMIT"');
625 }
626 $result = $connection->commit();
627 if ($logger !== null) {
628 $logger->stopQuery();
629 }
630 return $result;
631 }
632 private function commitAll() : void
633 {
634 while ($this->transactionNestingLevel !== 0) {
635 if ($this->autoCommit === \false && $this->transactionNestingLevel === 1) {
636 // When in no auto-commit mode, the last nesting commit immediately starts a new transaction.
637 // Therefore we need to do the final commit here and then leave to avoid an infinite loop.
638 $this->commit();
639 return;
640 }
641 $this->commit();
642 }
643 }
644 public function rollBack()
645 {
646 if ($this->transactionNestingLevel === 0) {
647 throw ConnectionException::noActiveTransaction();
648 }
649 $connection = $this->getWrappedConnection();
650 $logger = $this->_config->getSQLLogger();
651 if ($this->transactionNestingLevel === 1) {
652 if ($logger !== null) {
653 $logger->startQuery('"ROLLBACK"');
654 }
655 $this->transactionNestingLevel = 0;
656 $connection->rollBack();
657 $this->isRollbackOnly = \false;
658 if ($logger !== null) {
659 $logger->stopQuery();
660 }
661 if ($this->autoCommit === \false) {
662 $this->beginTransaction();
663 }
664 } elseif ($this->nestTransactionsWithSavepoints) {
665 if ($logger !== null) {
666 $logger->startQuery('"ROLLBACK TO SAVEPOINT"');
667 }
668 $this->rollbackSavepoint($this->_getNestedTransactionSavePointName());
669 --$this->transactionNestingLevel;
670 if ($logger !== null) {
671 $logger->stopQuery();
672 }
673 } else {
674 $this->isRollbackOnly = \true;
675 --$this->transactionNestingLevel;
676 }
677 $eventManager = $this->getEventManager();
678 if ($eventManager->hasListeners(Events::onTransactionRollBack)) {
679 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/5784', 'Subscribing to %s events is deprecated.', Events::onTransactionRollBack);
680 $eventManager->dispatchEvent(Events::onTransactionRollBack, new TransactionRollBackEventArgs($this));
681 }
682 return \true;
683 }
684 public function createSavepoint($savepoint)
685 {
686 $platform = $this->getDatabasePlatform();
687 if (!$platform->supportsSavepoints()) {
688 throw ConnectionException::savepointsNotSupported();
689 }
690 $this->executeStatement($platform->createSavePoint($savepoint));
691 }
692 public function releaseSavepoint($savepoint)
693 {
694 $logger = $this->_config->getSQLLogger();
695 $platform = $this->getDatabasePlatform();
696 if (!$platform->supportsSavepoints()) {
697 throw ConnectionException::savepointsNotSupported();
698 }
699 if (!$platform->supportsReleaseSavepoints()) {
700 if ($logger !== null) {
701 $logger->stopQuery();
702 }
703 return;
704 }
705 if ($logger !== null) {
706 $logger->startQuery('"RELEASE SAVEPOINT"');
707 }
708 $this->executeStatement($platform->releaseSavePoint($savepoint));
709 if ($logger === null) {
710 return;
711 }
712 $logger->stopQuery();
713 }
714 public function rollbackSavepoint($savepoint)
715 {
716 $platform = $this->getDatabasePlatform();
717 if (!$platform->supportsSavepoints()) {
718 throw ConnectionException::savepointsNotSupported();
719 }
720 $this->executeStatement($platform->rollbackSavePoint($savepoint));
721 }
722 public function getWrappedConnection()
723 {
724 Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/4966', 'Connection::getWrappedConnection() is deprecated.' . ' Use Connection::getNativeConnection() to access the native connection.');
725 $this->connect();
726 return $this->_conn;
727 }
728 public function getNativeConnection()
729 {
730 $this->connect();
731 if (!method_exists($this->_conn, 'getNativeConnection')) {
732 throw new LogicException(sprintf('The driver connection %s does not support accessing the native connection.', get_class($this->_conn)));
733 }
734 return $this->_conn->getNativeConnection();
735 }
736 public function createSchemaManager() : AbstractSchemaManager
737 {
738 return $this->schemaManagerFactory->createSchemaManager($this);
739 }
740 public function getSchemaManager()
741 {
742 Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/issues/4515', 'Connection::getSchemaManager() is deprecated, use Connection::createSchemaManager() instead.');
743 return $this->_schemaManager ??= $this->createSchemaManager();
744 }
745 public function setRollbackOnly()
746 {
747 if ($this->transactionNestingLevel === 0) {
748 throw ConnectionException::noActiveTransaction();
749 }
750 $this->isRollbackOnly = \true;
751 }
752 public function isRollbackOnly()
753 {
754 if ($this->transactionNestingLevel === 0) {
755 throw ConnectionException::noActiveTransaction();
756 }
757 return $this->isRollbackOnly;
758 }
759 public function convertToDatabaseValue($value, $type)
760 {
761 return Type::getType($type)->convertToDatabaseValue($value, $this->getDatabasePlatform());
762 }
763 public function convertToPHPValue($value, $type)
764 {
765 return Type::getType($type)->convertToPHPValue($value, $this->getDatabasePlatform());
766 }
767 private function bindParameters(DriverStatement $stmt, array $params, array $types) : void
768 {
769 // Check whether parameters are positional or named. Mixing is not allowed.
770 if (is_int(key($params))) {
771 $bindIndex = 1;
772 foreach ($params as $key => $value) {
773 if (isset($types[$key])) {
774 $type = $types[$key];
775 [$value, $bindingType] = $this->getBindingInfo($value, $type);
776 } else {
777 if (array_key_exists($key, $types)) {
778 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5550', 'Using NULL as prepared statement parameter type is deprecated.' . 'Omit or use ParameterType::STRING instead');
779 }
780 $bindingType = ParameterType::STRING;
781 }
782 $stmt->bindValue($bindIndex, $value, $bindingType);
783 ++$bindIndex;
784 }
785 } else {
786 // Named parameters
787 foreach ($params as $name => $value) {
788 if (isset($types[$name])) {
789 $type = $types[$name];
790 [$value, $bindingType] = $this->getBindingInfo($value, $type);
791 } else {
792 if (array_key_exists($name, $types)) {
793 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5550', 'Using NULL as prepared statement parameter type is deprecated.' . 'Omit or use ParameterType::STRING instead');
794 }
795 $bindingType = ParameterType::STRING;
796 }
797 $stmt->bindValue($name, $value, $bindingType);
798 }
799 }
800 }
801 private function getBindingInfo($value, $type) : array
802 {
803 if (is_string($type)) {
804 $type = Type::getType($type);
805 }
806 if ($type instanceof Type) {
807 $value = $type->convertToDatabaseValue($value, $this->getDatabasePlatform());
808 $bindingType = $type->getBindingType();
809 } else {
810 $bindingType = $type ?? ParameterType::STRING;
811 }
812 return [$value, $bindingType];
813 }
814 public function createQueryBuilder()
815 {
816 return new Query\QueryBuilder($this);
817 }
818 public final function convertExceptionDuringQuery(Driver\Exception $e, string $sql, array $params = [], array $types = []) : DriverException
819 {
820 return $this->handleDriverException($e, new Query($sql, $params, $types));
821 }
822 public final function convertException(Driver\Exception $e) : DriverException
823 {
824 return $this->handleDriverException($e, null);
825 }
826 private function expandArrayParameters(string $sql, array $params, array $types) : array
827 {
828 $this->parser ??= $this->getDatabasePlatform()->createSQLParser();
829 $visitor = new ExpandArrayParameters($params, $types);
830 $this->parser->parse($sql, $visitor);
831 return [$visitor->getSQL(), $visitor->getParameters(), $visitor->getTypes()];
832 }
833 private function needsArrayParameterConversion(array $params, array $types) : bool
834 {
835 if (is_string(key($params))) {
836 return \true;
837 }
838 foreach ($types as $type) {
839 if ($type === ArrayParameterType::INTEGER || $type === ArrayParameterType::STRING || $type === ArrayParameterType::ASCII || $type === ArrayParameterType::BINARY) {
840 return \true;
841 }
842 }
843 return \false;
844 }
845 private function handleDriverException(Driver\Exception $driverException, ?Query $query) : DriverException
846 {
847 $this->exceptionConverter ??= $this->_driver->getExceptionConverter();
848 $exception = $this->exceptionConverter->convert($driverException, $query);
849 if ($exception instanceof ConnectionLost) {
850 $this->close();
851 }
852 return $exception;
853 }
854 public function executeUpdate(string $sql, array $params = [], array $types = []) : int
855 {
856 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4163', '%s is deprecated, please use executeStatement() instead.', __METHOD__);
857 return $this->executeStatement($sql, $params, $types);
858 }
859 public function query(string $sql) : Result
860 {
861 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4163', '%s is deprecated, please use executeQuery() instead.', __METHOD__);
862 return $this->executeQuery($sql);
863 }
864 public function exec(string $sql) : int
865 {
866 Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4163', '%s is deprecated, please use executeStatement() instead.', __METHOD__);
867 return $this->executeStatement($sql);
868 }
869 }
870