Skip to content

Commit fccc826

Browse files
committed
Several improvements and error fixes to DBAL related code.
1 parent 478b8f6 commit fccc826

File tree

1 file changed

+41
-26
lines changed

1 file changed

+41
-26
lines changed

src/Symfony/Bridge/Doctrine/Security/SessionRegistry/SessionRegistryStorage.php

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Symfony\Bridge\Doctrine\Security\SessionRegistry;
44

55
use Doctrine\DBAL\Connection;
6+
use Doctrine\DBAL\DBALException;
67
use Symfony\Component\Security\Http\Session\SessionInformation;
78
use Symfony\Component\Security\Http\Session\SessionRegistryStorageInterface;
89

@@ -66,6 +67,8 @@ public function getSessionInformations($username, $includeExpiredSessions = fals
6667
$sessionInformations[] = $this->instantiateSessionInformationFromResultSet($data);
6768
}
6869

70+
$statement->closeCursor();
71+
6972
return $sessionInformations;
7073
}
7174

@@ -79,23 +82,30 @@ public function setSessionInformation(SessionInformation $sessionInformation)
7982
$mergeSql = $this->getMergeSql();
8083

8184
if (null !== $mergeSql) {
82-
$mergeStmt = $this->pdo->prepare($mergeSql);
83-
$mergeStmt->bindValue('session_id', $sessionInformation->getSessionId());
84-
$mergeStmt->bindValue('username', $sessionInformation->getUsername());
85-
$mergeStmt->bindValue('last_request', $sessionInformation->getLastRequest(), 'datetime');
86-
$mergeStmt->bindValue('expired', $sessionInformation->getExpired(), 'datetime');
87-
$mergeStmt->execute();
85+
$this->connection->executeQuery(
86+
$mergeSql,
87+
array(
88+
'session_id' => $sessionInformation->getSessionId(),
89+
'username' => $sessionInformation->getUsername(),
90+
'last_request' => $sessionInformation->getLastRequest(),
91+
'expired' => $sessionInformation->getExpired()
92+
),
93+
array(
94+
'last_request' => 'datetime',
95+
'expired' => 'datetime'
96+
)
97+
);
8898

8999
return true;
90100
}
91101

92-
$updateStmt = $this->pdo->prepare(
102+
$updateStmt = $this->connection->prepare(
93103
"UPDATE $this->table SET username=:username, last_request=:last_request, expired=:expired WHERE session_id = :session_id"
94104
);
95-
$mergeStmt->bindValue('session_id', $sessionInformation->getSessionId());
96-
$mergeStmt->bindValue('username', $sessionInformation->getUsername());
97-
$mergeStmt->bindValue('last_request', $sessionInformation->getLastRequest(), 'datetime');
98-
$mergeStmt->bindValue('expired', $sessionInformation->getExpired(), 'datetime');
105+
$updateStmt->bindValue('session_id', $sessionInformation->getSessionId());
106+
$updateStmt->bindValue('username', $sessionInformation->getUsername());
107+
$updateStmt->bindValue('last_request', $sessionInformation->getLastRequest(), 'datetime');
108+
$updateStmt->bindValue('expired', $sessionInformation->getExpired(), 'datetime');
99109
$updateStmt->execute();
100110

101111
// When MERGE is not supported, like in Postgres, we have to use this approach that can result in
@@ -105,17 +115,22 @@ public function setSessionInformation(SessionInformation $sessionInformation)
105115
// longer gap locking.
106116
if (!$updateStmt->rowCount()) {
107117
try {
108-
$insertStmt = $this->pdo->prepare(
109-
"INTO $this->table (session_id, username, last_request, expired) VALUES (:session_id, :username, :last_request, :expired)"
118+
$this->connection->insert(
119+
$this->table,
120+
array(
121+
'session_id' => $sessionInformation->getSessionId(),
122+
'username' => $sessionInformation->getUsername(),
123+
'last_request' => $sessionInformation->getLastRequest(),
124+
'expired' => $sessionInformation->getExpired()
125+
),
126+
array(
127+
'last_request' => 'datetime',
128+
'expired' => 'datetime'
129+
)
110130
);
111-
$insertStmt->bindValue('session_id', $sessionInformation->getSessionId());
112-
$insertStmt->bindValue('username', $sessionInformation->getUsername());
113-
$insertStmt->bindValue('last_request', $sessionInformation->getLastRequest(), 'datetime');
114-
$insertStmt->bindValue('expired', $sessionInformation->getExpired(), 'datetime');
115-
$insertStmt->execute();
116-
} catch (\PDOException $e) {
131+
} catch (DBALException $e) {
117132
// Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys
118-
if (0 === strpos($e->getCode(), '23')) {
133+
if ($e->getPrevious() instanceof \PDOException && 0 === strpos($e->getPrevious()->getCode(), '23')) {
119134
$updateStmt->execute();
120135
} else {
121136
throw $e;
@@ -151,24 +166,24 @@ private function instantiateSessionInformationFromResultSet($data)
151166
*/
152167
private function getMergeSql()
153168
{
154-
switch ($this->connection->getDriver()->getName()) {
155-
case 'pdo_mysql':
169+
switch ($this->connection->getDatabasePlatform()->getName()) {
170+
case 'mysql':
156171
return "INSERT INTO $this->table (session_id, username, last_request, expired) VALUES (:session_id, :username, :last_request, :expired) ".
157172
"ON DUPLICATE KEY UPDATE username = VALUES(username), last_request = VALUES(last_request), expired = VALUES(expired)";
158-
case 'pdo_oracle':
173+
case 'oracle':
159174
// DUAL is Oracle specific dummy table
160175
return "MERGE INTO $this->table USING DUAL ON (session_id= :session_id) ".
161176
"WHEN NOT MATCHED THEN INSERT (session_id, username, last_request, expired) VALUES (:session_id, :username, :last_request, :expired) ".
162177
"WHEN MATCHED THEN UPDATE SET username = :username, last_request = :last_request, expired = :expired";
163-
case 'pdo_sqlsrv':
164-
if (version_compare($this->connection->getWrappedConnection()->getAttribute(\PDO::ATTR_SERVER_VERSION), '10', '>=')) {
178+
case 'mssql':
179+
if ($this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SQLServer2008Platform || $this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SQLServer2012Platform) {
165180
// MERGE is only available since SQL Server 2008 and must be terminated by semicolon
166181
// It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx
167182
return "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON (session_id = :session_id) ".
168183
"WHEN NOT MATCHED THEN INSERT (session_id, username, last_request, expired) VALUES (:session_id, :username, :last_request, :expired) ".
169184
"WHEN MATCHED THEN UPDATE SET username = :username, last_request = :last_request, expired = :expired;";
170185
}
171-
case 'pdo_sqlite':
186+
case 'sqlite':
172187
return "INSERT OR REPLACE INTO $this->table (session_id, username, last_request, expired) VALUES (:session_id, :username, :last_request, :expired)";
173188
}
174189
}

0 commit comments

Comments
 (0)