|
11 | 11 |
|
12 | 12 | namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
13 | 13 |
|
| 14 | +use Doctrine\DBAL\Connection; |
| 15 | +use Doctrine\DBAL\Exception; |
| 16 | +use Doctrine\DBAL\Schema\AbstractSchemaManager; |
| 17 | +use Doctrine\DBAL\Schema\Schema; |
| 18 | +use Doctrine\DBAL\Schema\SchemaException; |
| 19 | +use Doctrine\DBAL\Types\Types; |
| 20 | + |
14 | 21 | /**
|
15 | 22 | * Session handler using a PDO connection to read and write data.
|
16 | 23 | *
|
@@ -175,6 +182,93 @@ public function __construct(\PDO|string $pdoOrDsn = null, array $options = [])
|
175 | 182 | $this->ttl = $options['ttl'] ?? null;
|
176 | 183 | }
|
177 | 184 |
|
| 185 | + /** |
| 186 | + * @param AbstractSchemaManager $schemaManager |
| 187 | + * |
| 188 | + * @return bool |
| 189 | + * @throws Exception |
| 190 | + */ |
| 191 | + private function isInListTablesWithoutFilter(AbstractSchemaManager $schemaManager) : bool |
| 192 | + { |
| 193 | + $tablesName = $schemaManager->listTableNames(); |
| 194 | + |
| 195 | + if (in_array($this->table, $tablesName)) { |
| 196 | + return true; |
| 197 | + } |
| 198 | + |
| 199 | + return false; |
| 200 | + } |
| 201 | + |
| 202 | + /** |
| 203 | + * @throws Exception |
| 204 | + */ |
| 205 | + public function configureSchema(Schema $schema, Connection $connection): void |
| 206 | + { |
| 207 | + $configuration = $connection->getConfiguration(); |
| 208 | + |
| 209 | + $schemaManager = method_exists(Connection::class, 'createSchemaManager') |
| 210 | + ? $connection->createSchemaManager() |
| 211 | + : $connection->getSchemaManager(); |
| 212 | + |
| 213 | + $configuration->setSchemaAssetsFilter(null); |
| 214 | + $isTableFound = $this->isInListTablesWithoutFilter($schemaManager); |
| 215 | + |
| 216 | + if ($isTableFound) { |
| 217 | + return; |
| 218 | + } |
| 219 | + |
| 220 | + $this->addTableToSchema($schema); |
| 221 | + } |
| 222 | + |
| 223 | + /** |
| 224 | + * @param Schema $schema |
| 225 | + * |
| 226 | + * @throws SchemaException |
| 227 | + */ |
| 228 | + private function addTableToSchema(Schema $schema) |
| 229 | + { |
| 230 | + $this->getConnection(); |
| 231 | + |
| 232 | + $table = $schema->createTable($this->table); |
| 233 | + switch ($this->driver) { |
| 234 | + case 'mysql': |
| 235 | + $table->addColumn($this->idCol, Types::BINARY)->setLength(128)->setNotnull(true); |
| 236 | + $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true); |
| 237 | + $table->addColumn($this->lifetimeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true); |
| 238 | + $table->addColumn($this->timeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true); |
| 239 | + $table->addOption('collate', 'utf8mb4_bin'); |
| 240 | + $table->addOption('engine', 'InnoDB'); |
| 241 | + break; |
| 242 | + case 'sqlite': |
| 243 | + $table->addColumn($this->idCol, Types::TEXT)->setNotnull(true); |
| 244 | + $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true); |
| 245 | + $table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true); |
| 246 | + $table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true); |
| 247 | + break; |
| 248 | + case 'pgsql': |
| 249 | + $table->addColumn($this->idCol, Types::STRING)->setLength(128)->setNotnull(true); |
| 250 | + $table->addColumn($this->dataCol, Types::BINARY)->setNotnull(true); |
| 251 | + $table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true); |
| 252 | + $table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true); |
| 253 | + break; |
| 254 | + case 'oci': |
| 255 | + $table->addColumn($this->idCol, Types::STRING)->setLength(128)->setNotnull(true); |
| 256 | + $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true); |
| 257 | + $table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true); |
| 258 | + $table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true); |
| 259 | + break; |
| 260 | + case 'sqlsrv': |
| 261 | + $table->addColumn($this->idCol, Types::TEXT)->setLength(128)->setNotnull(true); |
| 262 | + $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true); |
| 263 | + $table->addColumn($this->lifetimeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true); |
| 264 | + $table->addColumn($this->timeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true); |
| 265 | + break; |
| 266 | + default: |
| 267 | + throw new \DomainException(sprintf('Creating the session table is currently not implemented for PDO driver "%s".', $this->driver)); |
| 268 | + } |
| 269 | + $table->setPrimaryKey([$this->idCol]); |
| 270 | + } |
| 271 | + |
178 | 272 | /**
|
179 | 273 | * Creates the table to store sessions which can be called once for setup.
|
180 | 274 | *
|
|
0 commit comments