diff options
Diffstat (limited to 'vendor/doctrine/orm/src/Query/Exec')
5 files changed, 445 insertions, 0 deletions
diff --git a/vendor/doctrine/orm/src/Query/Exec/AbstractSqlExecutor.php b/vendor/doctrine/orm/src/Query/Exec/AbstractSqlExecutor.php new file mode 100644 index 0000000..101bf26 --- /dev/null +++ b/vendor/doctrine/orm/src/Query/Exec/AbstractSqlExecutor.php | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | <?php | ||
| 2 | |||
| 3 | declare(strict_types=1); | ||
| 4 | |||
| 5 | namespace Doctrine\ORM\Query\Exec; | ||
| 6 | |||
| 7 | use Doctrine\DBAL\ArrayParameterType; | ||
| 8 | use Doctrine\DBAL\Cache\QueryCacheProfile; | ||
| 9 | use Doctrine\DBAL\Connection; | ||
| 10 | use Doctrine\DBAL\ParameterType; | ||
| 11 | use Doctrine\DBAL\Result; | ||
| 12 | use Doctrine\DBAL\Types\Type; | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Base class for SQL statement executors. | ||
| 16 | * | ||
| 17 | * @link http://www.doctrine-project.org | ||
| 18 | * | ||
| 19 | * @todo Rename: AbstractSQLExecutor | ||
| 20 | * @psalm-type WrapperParameterType = string|Type|ParameterType::*|ArrayParameterType::* | ||
| 21 | * @psalm-type WrapperParameterTypeArray = array<int<0, max>, WrapperParameterType>|array<string, WrapperParameterType> | ||
| 22 | */ | ||
| 23 | abstract class AbstractSqlExecutor | ||
| 24 | { | ||
| 25 | /** @var list<string>|string */ | ||
| 26 | protected array|string $sqlStatements; | ||
| 27 | |||
| 28 | protected QueryCacheProfile|null $queryCacheProfile = null; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Gets the SQL statements that are executed by the executor. | ||
| 32 | * | ||
| 33 | * @return list<string>|string All the SQL update statements. | ||
| 34 | */ | ||
| 35 | public function getSqlStatements(): array|string | ||
| 36 | { | ||
| 37 | return $this->sqlStatements; | ||
| 38 | } | ||
| 39 | |||
| 40 | public function setQueryCacheProfile(QueryCacheProfile $qcp): void | ||
| 41 | { | ||
| 42 | $this->queryCacheProfile = $qcp; | ||
| 43 | } | ||
| 44 | |||
| 45 | /** | ||
| 46 | * Do not use query cache | ||
| 47 | */ | ||
| 48 | public function removeQueryCacheProfile(): void | ||
| 49 | { | ||
| 50 | $this->queryCacheProfile = null; | ||
| 51 | } | ||
| 52 | |||
| 53 | /** | ||
| 54 | * Executes all sql statements. | ||
| 55 | * | ||
| 56 | * @param Connection $conn The database connection that is used to execute the queries. | ||
| 57 | * @param list<mixed>|array<string, mixed> $params The parameters. | ||
| 58 | * @psalm-param WrapperParameterTypeArray $types The parameter types. | ||
| 59 | */ | ||
| 60 | abstract public function execute(Connection $conn, array $params, array $types): Result|int; | ||
| 61 | } | ||
diff --git a/vendor/doctrine/orm/src/Query/Exec/MultiTableDeleteExecutor.php b/vendor/doctrine/orm/src/Query/Exec/MultiTableDeleteExecutor.php new file mode 100644 index 0000000..6096462 --- /dev/null +++ b/vendor/doctrine/orm/src/Query/Exec/MultiTableDeleteExecutor.php | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | <?php | ||
| 2 | |||
| 3 | declare(strict_types=1); | ||
| 4 | |||
| 5 | namespace Doctrine\ORM\Query\Exec; | ||
| 6 | |||
| 7 | use Doctrine\DBAL\Connection; | ||
| 8 | use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection; | ||
| 9 | use Doctrine\DBAL\Types\Type; | ||
| 10 | use Doctrine\ORM\Query\AST; | ||
| 11 | use Doctrine\ORM\Query\AST\DeleteStatement; | ||
| 12 | use Doctrine\ORM\Query\SqlWalker; | ||
| 13 | use Doctrine\ORM\Utility\PersisterHelper; | ||
| 14 | use Throwable; | ||
| 15 | |||
| 16 | use function array_reverse; | ||
| 17 | use function implode; | ||
| 18 | |||
| 19 | /** | ||
| 20 | * Executes the SQL statements for bulk DQL DELETE statements on classes in | ||
| 21 | * Class Table Inheritance (JOINED). | ||
| 22 | * | ||
| 23 | * @link http://www.doctrine-project.org | ||
| 24 | */ | ||
| 25 | class MultiTableDeleteExecutor extends AbstractSqlExecutor | ||
| 26 | { | ||
| 27 | private readonly string $createTempTableSql; | ||
| 28 | private readonly string $dropTempTableSql; | ||
| 29 | private readonly string $insertSql; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * Initializes a new <tt>MultiTableDeleteExecutor</tt>. | ||
| 33 | * | ||
| 34 | * Internal note: Any SQL construction and preparation takes place in the constructor for | ||
| 35 | * best performance. With a query cache the executor will be cached. | ||
| 36 | * | ||
| 37 | * @param DeleteStatement $AST The root AST node of the DQL query. | ||
| 38 | * @param SqlWalker $sqlWalker The walker used for SQL generation from the AST. | ||
| 39 | */ | ||
| 40 | public function __construct(AST\Node $AST, SqlWalker $sqlWalker) | ||
| 41 | { | ||
| 42 | $em = $sqlWalker->getEntityManager(); | ||
| 43 | $conn = $em->getConnection(); | ||
| 44 | $platform = $conn->getDatabasePlatform(); | ||
| 45 | $quoteStrategy = $em->getConfiguration()->getQuoteStrategy(); | ||
| 46 | |||
| 47 | if ($conn instanceof PrimaryReadReplicaConnection) { | ||
| 48 | $conn->ensureConnectedToPrimary(); | ||
| 49 | } | ||
| 50 | |||
| 51 | $primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName); | ||
| 52 | $primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable; | ||
| 53 | $rootClass = $em->getClassMetadata($primaryClass->rootEntityName); | ||
| 54 | |||
| 55 | $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName()); | ||
| 56 | $idColumnNames = $rootClass->getIdentifierColumnNames(); | ||
| 57 | $idColumnList = implode(', ', $idColumnNames); | ||
| 58 | |||
| 59 | // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause() | ||
| 60 | $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $primaryDqlAlias); | ||
| 61 | |||
| 62 | $insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' | ||
| 63 | . ' SELECT t0.' . implode(', t0.', $idColumnNames); | ||
| 64 | |||
| 65 | $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $primaryDqlAlias); | ||
| 66 | $fromClause = new AST\FromClause([new AST\IdentificationVariableDeclaration($rangeDecl, null, [])]); | ||
| 67 | $insertSql .= $sqlWalker->walkFromClause($fromClause); | ||
| 68 | |||
| 69 | // Append WHERE clause, if there is one. | ||
| 70 | if ($AST->whereClause) { | ||
| 71 | $insertSql .= $sqlWalker->walkWhereClause($AST->whereClause); | ||
| 72 | } | ||
| 73 | |||
| 74 | $this->insertSql = $insertSql; | ||
| 75 | |||
| 76 | // 2. Create ID subselect statement used in DELETE ... WHERE ... IN (subselect) | ||
| 77 | $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable; | ||
| 78 | |||
| 79 | // 3. Create and store DELETE statements | ||
| 80 | $classNames = [...$primaryClass->parentClasses, ...[$primaryClass->name], ...$primaryClass->subClasses]; | ||
| 81 | foreach (array_reverse($classNames) as $className) { | ||
| 82 | $tableName = $quoteStrategy->getTableName($em->getClassMetadata($className), $platform); | ||
| 83 | $this->sqlStatements[] = 'DELETE FROM ' . $tableName | ||
| 84 | . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; | ||
| 85 | } | ||
| 86 | |||
| 87 | // 4. Store DDL for temporary identifier table. | ||
| 88 | $columnDefinitions = []; | ||
| 89 | foreach ($idColumnNames as $idColumnName) { | ||
| 90 | $columnDefinitions[$idColumnName] = [ | ||
| 91 | 'name' => $idColumnName, | ||
| 92 | 'notnull' => true, | ||
| 93 | 'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)), | ||
| 94 | ]; | ||
| 95 | } | ||
| 96 | |||
| 97 | $this->createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' | ||
| 98 | . $platform->getColumnDeclarationListSQL($columnDefinitions) . ', PRIMARY KEY(' . implode(',', $idColumnNames) . '))'; | ||
| 99 | $this->dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable); | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 103 | * {@inheritDoc} | ||
| 104 | */ | ||
| 105 | public function execute(Connection $conn, array $params, array $types): int | ||
| 106 | { | ||
| 107 | // Create temporary id table | ||
| 108 | $conn->executeStatement($this->createTempTableSql); | ||
| 109 | |||
| 110 | try { | ||
| 111 | // Insert identifiers | ||
| 112 | $numDeleted = $conn->executeStatement($this->insertSql, $params, $types); | ||
| 113 | |||
| 114 | // Execute DELETE statements | ||
| 115 | foreach ($this->sqlStatements as $sql) { | ||
| 116 | $conn->executeStatement($sql); | ||
| 117 | } | ||
| 118 | } catch (Throwable $exception) { | ||
| 119 | // FAILURE! Drop temporary table to avoid possible collisions | ||
| 120 | $conn->executeStatement($this->dropTempTableSql); | ||
| 121 | |||
| 122 | // Re-throw exception | ||
| 123 | throw $exception; | ||
| 124 | } | ||
| 125 | |||
| 126 | // Drop temporary table | ||
| 127 | $conn->executeStatement($this->dropTempTableSql); | ||
| 128 | |||
| 129 | return $numDeleted; | ||
| 130 | } | ||
| 131 | } | ||
diff --git a/vendor/doctrine/orm/src/Query/Exec/MultiTableUpdateExecutor.php b/vendor/doctrine/orm/src/Query/Exec/MultiTableUpdateExecutor.php new file mode 100644 index 0000000..dab1b61 --- /dev/null +++ b/vendor/doctrine/orm/src/Query/Exec/MultiTableUpdateExecutor.php | |||
| @@ -0,0 +1,180 @@ | |||
| 1 | <?php | ||
| 2 | |||
| 3 | declare(strict_types=1); | ||
| 4 | |||
| 5 | namespace Doctrine\ORM\Query\Exec; | ||
| 6 | |||
| 7 | use Doctrine\DBAL\Connection; | ||
| 8 | use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection; | ||
| 9 | use Doctrine\DBAL\Types\Type; | ||
| 10 | use Doctrine\ORM\Query\AST; | ||
| 11 | use Doctrine\ORM\Query\AST\UpdateStatement; | ||
| 12 | use Doctrine\ORM\Query\ParameterTypeInferer; | ||
| 13 | use Doctrine\ORM\Query\SqlWalker; | ||
| 14 | use Doctrine\ORM\Utility\PersisterHelper; | ||
| 15 | |||
| 16 | use function array_reverse; | ||
| 17 | use function array_slice; | ||
| 18 | use function implode; | ||
| 19 | |||
| 20 | /** | ||
| 21 | * Executes the SQL statements for bulk DQL UPDATE statements on classes in | ||
| 22 | * Class Table Inheritance (JOINED). | ||
| 23 | */ | ||
| 24 | class MultiTableUpdateExecutor extends AbstractSqlExecutor | ||
| 25 | { | ||
| 26 | private readonly string $createTempTableSql; | ||
| 27 | private readonly string $dropTempTableSql; | ||
| 28 | private readonly string $insertSql; | ||
| 29 | |||
| 30 | /** @var mixed[] */ | ||
| 31 | private array $sqlParameters = []; | ||
| 32 | private int $numParametersInUpdateClause = 0; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * Initializes a new <tt>MultiTableUpdateExecutor</tt>. | ||
| 36 | * | ||
| 37 | * Internal note: Any SQL construction and preparation takes place in the constructor for | ||
| 38 | * best performance. With a query cache the executor will be cached. | ||
| 39 | * | ||
| 40 | * @param UpdateStatement $AST The root AST node of the DQL query. | ||
| 41 | * @param SqlWalker $sqlWalker The walker used for SQL generation from the AST. | ||
| 42 | */ | ||
| 43 | public function __construct(AST\Node $AST, SqlWalker $sqlWalker) | ||
| 44 | { | ||
| 45 | $em = $sqlWalker->getEntityManager(); | ||
| 46 | $conn = $em->getConnection(); | ||
| 47 | $platform = $conn->getDatabasePlatform(); | ||
| 48 | $quoteStrategy = $em->getConfiguration()->getQuoteStrategy(); | ||
| 49 | $this->sqlStatements = []; | ||
| 50 | |||
| 51 | if ($conn instanceof PrimaryReadReplicaConnection) { | ||
| 52 | $conn->ensureConnectedToPrimary(); | ||
| 53 | } | ||
| 54 | |||
| 55 | $updateClause = $AST->updateClause; | ||
| 56 | $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName); | ||
| 57 | $rootClass = $em->getClassMetadata($primaryClass->rootEntityName); | ||
| 58 | |||
| 59 | $updateItems = $updateClause->updateItems; | ||
| 60 | |||
| 61 | $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName()); | ||
| 62 | $idColumnNames = $rootClass->getIdentifierColumnNames(); | ||
| 63 | $idColumnList = implode(', ', $idColumnNames); | ||
| 64 | |||
| 65 | // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause() | ||
| 66 | $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $updateClause->aliasIdentificationVariable); | ||
| 67 | |||
| 68 | $insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' | ||
| 69 | . ' SELECT t0.' . implode(', t0.', $idColumnNames); | ||
| 70 | |||
| 71 | $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $updateClause->aliasIdentificationVariable); | ||
| 72 | $fromClause = new AST\FromClause([new AST\IdentificationVariableDeclaration($rangeDecl, null, [])]); | ||
| 73 | |||
| 74 | $insertSql .= $sqlWalker->walkFromClause($fromClause); | ||
| 75 | |||
| 76 | // 2. Create ID subselect statement used in UPDATE ... WHERE ... IN (subselect) | ||
| 77 | $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable; | ||
| 78 | |||
| 79 | // 3. Create and store UPDATE statements | ||
| 80 | $classNames = [...$primaryClass->parentClasses, ...[$primaryClass->name], ...$primaryClass->subClasses]; | ||
| 81 | |||
| 82 | foreach (array_reverse($classNames) as $className) { | ||
| 83 | $affected = false; | ||
| 84 | $class = $em->getClassMetadata($className); | ||
| 85 | $updateSql = 'UPDATE ' . $quoteStrategy->getTableName($class, $platform) . ' SET '; | ||
| 86 | |||
| 87 | $sqlParameters = []; | ||
| 88 | foreach ($updateItems as $updateItem) { | ||
| 89 | $field = $updateItem->pathExpression->field; | ||
| 90 | |||
| 91 | if ( | ||
| 92 | (isset($class->fieldMappings[$field]) && ! isset($class->fieldMappings[$field]->inherited)) || | ||
| 93 | (isset($class->associationMappings[$field]) && ! isset($class->associationMappings[$field]->inherited)) | ||
| 94 | ) { | ||
| 95 | $newValue = $updateItem->newValue; | ||
| 96 | |||
| 97 | if (! $affected) { | ||
| 98 | $affected = true; | ||
| 99 | } else { | ||
| 100 | $updateSql .= ', '; | ||
| 101 | } | ||
| 102 | |||
| 103 | $updateSql .= $sqlWalker->walkUpdateItem($updateItem); | ||
| 104 | |||
| 105 | if ($newValue instanceof AST\InputParameter) { | ||
| 106 | $sqlParameters[] = $newValue->name; | ||
| 107 | |||
| 108 | ++$this->numParametersInUpdateClause; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | if ($affected) { | ||
| 114 | $this->sqlParameters[] = $sqlParameters; | ||
| 115 | $this->sqlStatements[] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | // Append WHERE clause to insertSql, if there is one. | ||
| 120 | if ($AST->whereClause) { | ||
| 121 | $insertSql .= $sqlWalker->walkWhereClause($AST->whereClause); | ||
| 122 | } | ||
| 123 | |||
| 124 | $this->insertSql = $insertSql; | ||
| 125 | |||
| 126 | // 4. Store DDL for temporary identifier table. | ||
| 127 | $columnDefinitions = []; | ||
| 128 | |||
| 129 | foreach ($idColumnNames as $idColumnName) { | ||
| 130 | $columnDefinitions[$idColumnName] = [ | ||
| 131 | 'name' => $idColumnName, | ||
| 132 | 'notnull' => true, | ||
| 133 | 'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)), | ||
| 134 | ]; | ||
| 135 | } | ||
| 136 | |||
| 137 | $this->createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' | ||
| 138 | . $platform->getColumnDeclarationListSQL($columnDefinitions) . ', PRIMARY KEY(' . implode(',', $idColumnNames) . '))'; | ||
| 139 | |||
| 140 | $this->dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable); | ||
| 141 | } | ||
| 142 | |||
| 143 | /** | ||
| 144 | * {@inheritDoc} | ||
| 145 | */ | ||
| 146 | public function execute(Connection $conn, array $params, array $types): int | ||
| 147 | { | ||
| 148 | // Create temporary id table | ||
| 149 | $conn->executeStatement($this->createTempTableSql); | ||
| 150 | |||
| 151 | try { | ||
| 152 | // Insert identifiers. Parameters from the update clause are cut off. | ||
| 153 | $numUpdated = $conn->executeStatement( | ||
| 154 | $this->insertSql, | ||
| 155 | array_slice($params, $this->numParametersInUpdateClause), | ||
| 156 | array_slice($types, $this->numParametersInUpdateClause), | ||
| 157 | ); | ||
| 158 | |||
| 159 | // Execute UPDATE statements | ||
| 160 | foreach ($this->sqlStatements as $key => $statement) { | ||
| 161 | $paramValues = []; | ||
| 162 | $paramTypes = []; | ||
| 163 | |||
| 164 | if (isset($this->sqlParameters[$key])) { | ||
| 165 | foreach ($this->sqlParameters[$key] as $parameterKey => $parameterName) { | ||
| 166 | $paramValues[] = $params[$parameterKey]; | ||
| 167 | $paramTypes[] = $types[$parameterKey] ?? ParameterTypeInferer::inferType($params[$parameterKey]); | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | $conn->executeStatement($statement, $paramValues, $paramTypes); | ||
| 172 | } | ||
| 173 | } finally { | ||
| 174 | // Drop temporary table | ||
| 175 | $conn->executeStatement($this->dropTempTableSql); | ||
| 176 | } | ||
| 177 | |||
| 178 | return $numUpdated; | ||
| 179 | } | ||
| 180 | } | ||
diff --git a/vendor/doctrine/orm/src/Query/Exec/SingleSelectExecutor.php b/vendor/doctrine/orm/src/Query/Exec/SingleSelectExecutor.php new file mode 100644 index 0000000..5445edb --- /dev/null +++ b/vendor/doctrine/orm/src/Query/Exec/SingleSelectExecutor.php | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | <?php | ||
| 2 | |||
| 3 | declare(strict_types=1); | ||
| 4 | |||
| 5 | namespace Doctrine\ORM\Query\Exec; | ||
| 6 | |||
| 7 | use Doctrine\DBAL\Connection; | ||
| 8 | use Doctrine\DBAL\Result; | ||
| 9 | use Doctrine\ORM\Query\AST\SelectStatement; | ||
| 10 | use Doctrine\ORM\Query\SqlWalker; | ||
| 11 | |||
| 12 | /** | ||
| 13 | * Executor that executes the SQL statement for simple DQL SELECT statements. | ||
| 14 | * | ||
| 15 | * @link www.doctrine-project.org | ||
| 16 | */ | ||
| 17 | class SingleSelectExecutor extends AbstractSqlExecutor | ||
| 18 | { | ||
| 19 | public function __construct(SelectStatement $AST, SqlWalker $sqlWalker) | ||
| 20 | { | ||
| 21 | $this->sqlStatements = $sqlWalker->walkSelectStatement($AST); | ||
| 22 | } | ||
| 23 | |||
| 24 | /** | ||
| 25 | * {@inheritDoc} | ||
| 26 | */ | ||
| 27 | public function execute(Connection $conn, array $params, array $types): Result | ||
| 28 | { | ||
| 29 | return $conn->executeQuery($this->sqlStatements, $params, $types, $this->queryCacheProfile); | ||
| 30 | } | ||
| 31 | } | ||
diff --git a/vendor/doctrine/orm/src/Query/Exec/SingleTableDeleteUpdateExecutor.php b/vendor/doctrine/orm/src/Query/Exec/SingleTableDeleteUpdateExecutor.php new file mode 100644 index 0000000..66696db --- /dev/null +++ b/vendor/doctrine/orm/src/Query/Exec/SingleTableDeleteUpdateExecutor.php | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | <?php | ||
| 2 | |||
| 3 | declare(strict_types=1); | ||
| 4 | |||
| 5 | namespace Doctrine\ORM\Query\Exec; | ||
| 6 | |||
| 7 | use Doctrine\DBAL\Connection; | ||
| 8 | use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection; | ||
| 9 | use Doctrine\ORM\Query\AST; | ||
| 10 | use Doctrine\ORM\Query\SqlWalker; | ||
| 11 | |||
| 12 | /** | ||
| 13 | * Executor that executes the SQL statements for DQL DELETE/UPDATE statements on classes | ||
| 14 | * that are mapped to a single table. | ||
| 15 | * | ||
| 16 | * @link www.doctrine-project.org | ||
| 17 | * | ||
| 18 | * @todo This is exactly the same as SingleSelectExecutor. Unify in SingleStatementExecutor. | ||
| 19 | */ | ||
| 20 | class SingleTableDeleteUpdateExecutor extends AbstractSqlExecutor | ||
| 21 | { | ||
| 22 | public function __construct(AST\Node $AST, SqlWalker $sqlWalker) | ||
| 23 | { | ||
| 24 | if ($AST instanceof AST\UpdateStatement) { | ||
| 25 | $this->sqlStatements = $sqlWalker->walkUpdateStatement($AST); | ||
| 26 | } elseif ($AST instanceof AST\DeleteStatement) { | ||
| 27 | $this->sqlStatements = $sqlWalker->walkDeleteStatement($AST); | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | /** | ||
| 32 | * {@inheritDoc} | ||
| 33 | */ | ||
| 34 | public function execute(Connection $conn, array $params, array $types): int | ||
| 35 | { | ||
| 36 | if ($conn instanceof PrimaryReadReplicaConnection) { | ||
| 37 | $conn->ensureConnectedToPrimary(); | ||
| 38 | } | ||
| 39 | |||
| 40 | return $conn->executeStatement($this->sqlStatements, $params, $types); | ||
| 41 | } | ||
| 42 | } | ||
