ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
SimpleSAML\Store\SQL Class Reference
+ Inheritance diagram for SimpleSAML\Store\SQL:
+ Collaboration diagram for SimpleSAML\Store\SQL:

Public Member Functions

 __construct ()
 Initialize the SQL data store. More...
 
 getTableVersion ($name)
 Get table version. More...
 
 setTableVersion ($name, $version)
 Set table version. More...
 
 insertOrUpdate ($table, array $keys, array $data)
 Insert or update a key-value in the store. More...
 
 get ($type, $key)
 Retrieve a value from the data store. More...
 
 set ($type, $key, $value, $expire=null)
 Save a value in the data store. More...
 
 delete ($type, $key)
 Delete an entry from the data store. More...
 
 get ($type, $key)
 Retrieve a value from the data store. More...
 
 set ($type, $key, $value, $expire=null)
 Save a value to the data store. More...
 
 delete ($type, $key)
 Delete a value from the data store. More...
 

Data Fields

 $pdo
 
 $driver
 
 $prefix
 

Private Member Functions

 initTableVersionTable ()
 Initialize the table-version table. More...
 
 initKVTable ()
 Initialize key-value table. More...
 
 cleanKVStore ()
 Clean the key-value table of expired entries. More...
 

Private Attributes

 $tableVersions
 

Additional Inherited Members

- Static Public Member Functions inherited from SimpleSAML\Store
static getInstance ()
 Retrieve our singleton instance. More...
 

Detailed Description

Definition at line 14 of file SQL.php.

Constructor & Destructor Documentation

◆ __construct()

SimpleSAML\Store\SQL::__construct ( )

Initialize the SQL data store.

Definition at line 51 of file SQL.php.

52 {
53 $config = Configuration::getInstance();
54
55 $dsn = $config->getString('store.sql.dsn');
56 $username = $config->getString('store.sql.username', null);
57 $password = $config->getString('store.sql.password', null);
58 $options = $config->getArray('store.sql.options', null);
59 $this->prefix = $config->getString('store.sql.prefix', 'simpleSAMLphp');
60 try {
61 $this->pdo = new \PDO($dsn, $username, $password, $options);
62 } catch (\PDOException $e) {
63 throw new \Exception("Database error: " . $e->getMessage());
64 }
65 $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
66
67 $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
68
69 if ($this->driver === 'mysql') {
70 $this->pdo->exec('SET time_zone = "+00:00"');
71 }
72
73 $this->initTableVersionTable();
74 $this->initKVTable();
75 }
initTableVersionTable()
Initialize the table-version table.
Definition: SQL.php:81
initKVTable()
Initialize key-value table.
Definition: SQL.php:104
$password
Definition: cron.php:14
$config
Definition: bootstrap.php:15
foreach($paths as $path) $dsn
Definition: migrateto20.php:56

References $config, $dsn, PHPMailer\PHPMailer\$options, $password, SimpleSAML\Store\SQL\initKVTable(), and SimpleSAML\Store\SQL\initTableVersionTable().

+ Here is the call graph for this function:

Member Function Documentation

◆ cleanKVStore()

SimpleSAML\Store\SQL::cleanKVStore ( )
private

Clean the key-value table of expired entries.

Definition at line 270 of file SQL.php.

271 {
272 Logger::debug('store.sql: Cleaning key-value store.');
273
274 $query = 'DELETE FROM '.$this->prefix.'_kvstore WHERE _expire < :now';
275 $params = array('now' => gmdate('Y-m-d H:i:s'));
276
277 $query = $this->pdo->prepare($query);
278 $query->execute($params);
279 }
static debug($string)
Definition: Logger.php:211
$query

References PHPMailer\PHPMailer\$params, $query, and SimpleSAML\Logger\debug().

Referenced by SimpleSAML\Store\SQL\set().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ delete()

SimpleSAML\Store\SQL::delete (   $type,
  $key 
)

Delete an entry from the data store.

Parameters
string$typeThe type of the data
string$keyThe key to delete.

Reimplemented from SimpleSAML\Store.

Definition at line 371 of file SQL.php.

372 {
373 assert(is_string($type));
374 assert(is_string($key));
375
376 if (strlen($key) > 50) {
377 $key = sha1($key);
378 }
379
380 $data = array(
381 '_type' => $type,
382 '_key' => $key,
383 );
384
385 $query = 'DELETE FROM '.$this->prefix.'_kvstore WHERE _type=:_type AND _key=:_key';
386 $query = $this->pdo->prepare($query);
387 $query->execute($data);
388 }
$key
Definition: croninfo.php:18
$type
$data
Definition: bench.php:6

References $data, $key, $query, and $type.

◆ get()

SimpleSAML\Store\SQL::get (   $type,
  $key 
)

Retrieve a value from the data store.

Parameters
string$typeThe type of the data.
string$keyThe key to retrieve.
Returns
mixed|null The value associated with that key, or null if there's no such key.

Reimplemented from SimpleSAML\Store.

Definition at line 290 of file SQL.php.

291 {
292 assert(is_string($type));
293 assert(is_string($key));
294
295 if (strlen($key) > 50) {
296 $key = sha1($key);
297 }
298
299 $query = 'SELECT _value FROM '.$this->prefix.
300 '_kvstore WHERE _type = :type AND _key = :key AND (_expire IS NULL OR _expire > :now)';
301 $params = array('type' => $type, 'key' => $key, 'now' => gmdate('Y-m-d H:i:s'));
302
303 $query = $this->pdo->prepare($query);
304 $query->execute($params);
305
306 $row = $query->fetch(\PDO::FETCH_ASSOC);
307 if ($row === false) {
308 return null;
309 }
310
311 $value = $row['_value'];
312 if (is_resource($value)) {
313 $value = stream_get_contents($value);
314 }
315 $value = urldecode($value);
316 $value = unserialize($value);
317
318 if ($value === false) {
319 return null;
320 }
321 return $value;
322 }
$row

References $key, PHPMailer\PHPMailer\$params, $query, $row, and $type.

◆ getTableVersion()

SimpleSAML\Store\SQL::getTableVersion (   $name)

Get table version.

Parameters
string$nameTable name.
Returns
int The table version, or 0 if the table doesn't exist.

Definition at line 171 of file SQL.php.

172 {
173 assert(is_string($name));
174
175 if (!isset($this->tableVersions[$name])) {
176 return 0;
177 }
178
179 return $this->tableVersions[$name];
180 }

References $name.

Referenced by SimpleSAML\Store\SQL\initKVTable().

+ Here is the caller graph for this function:

◆ initKVTable()

SimpleSAML\Store\SQL::initKVTable ( )
private

Initialize key-value table.

Queries for updates, grouped by version. New updates can be added as a new array in this array

This upgrade removes the default NOT NULL constraint on the _expire field in MySQL. Because SQLite does not support field alterations, the approach is to: Create a new table without the NOT NULL constraint Copy the current data to the new table Drop the old table Rename the new table correctly Readd the index

Definition at line 104 of file SQL.php.

105 {
106 $current_version = $this->getTableVersion('kvstore');
107
108 $text_t = 'TEXT';
109 if ($this->driver === 'mysql') {
110 // TEXT data type has size constraints that can be hit at some point, so we use LONGTEXT instead
111 $text_t = 'LONGTEXT';
112 }
113
118 $table_updates = array(
119 array(
120 'CREATE TABLE '.$this->prefix.
121 '_kvstore (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value '.$text_t.
122 ' NOT NULL, _expire TIMESTAMP, PRIMARY KEY (_key, _type))',
123 'CREATE INDEX '.$this->prefix.'_kvstore_expire ON '.$this->prefix.'_kvstore (_expire)'
124 ),
134 array(
135 'CREATE TABLE '.$this->prefix.
136 '_kvstore_new (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value '.$text_t.
137 ' NOT NULL, _expire TIMESTAMP NULL, PRIMARY KEY (_key, _type))',
138 'INSERT INTO '.$this->prefix.'_kvstore_new SELECT * FROM ' . $this->prefix.'_kvstore',
139 'DROP TABLE '.$this->prefix.'_kvstore',
140 'ALTER TABLE '.$this->prefix.'_kvstore_new RENAME TO ' . $this->prefix . '_kvstore',
141 'CREATE INDEX '.$this->prefix.'_kvstore_expire ON '.$this->prefix.'_kvstore (_expire)'
142 )
143 );
144
145 $latest_version = count($table_updates);
146
147 if ($current_version == $latest_version) {
148 return;
149 }
150
151 // Only run queries for after the current version
152 $updates_to_run = array_slice($table_updates, $current_version);
153
154 foreach ($updates_to_run as $version_updates) {
155 foreach ($version_updates as $query) {
156 $this->pdo->exec($query);
157 }
158 }
159
160 $this->setTableVersion('kvstore', $latest_version);
161 }
setTableVersion($name, $version)
Set table version.
Definition: SQL.php:189
getTableVersion($name)
Get table version.
Definition: SQL.php:171

References $query, SimpleSAML\Store\SQL\getTableVersion(), and SimpleSAML\Store\SQL\setTableVersion().

Referenced by SimpleSAML\Store\SQL\__construct().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initTableVersionTable()

SimpleSAML\Store\SQL::initTableVersionTable ( )
private

Initialize the table-version table.

Definition at line 81 of file SQL.php.

82 {
83 $this->tableVersions = array();
84
85 try {
86 $fetchTableVersion = $this->pdo->query('SELECT _name, _version FROM '.$this->prefix.'_tableVersion');
87 } catch (\PDOException $e) {
88 $this->pdo->exec(
89 'CREATE TABLE '.$this->prefix.
90 '_tableVersion (_name VARCHAR(30) NOT NULL UNIQUE, _version INTEGER NOT NULL)'
91 );
92 return;
93 }
94
95 while (($row = $fetchTableVersion->fetch(\PDO::FETCH_ASSOC)) !== false) {
96 $this->tableVersions[$row['_name']] = (int) $row['_version'];
97 }
98 }

References $row.

Referenced by SimpleSAML\Store\SQL\__construct().

+ Here is the caller graph for this function:

◆ insertOrUpdate()

SimpleSAML\Store\SQL::insertOrUpdate (   $table,
array  $keys,
array  $data 
)

Insert or update a key-value in the store.

Since various databases implement different methods for doing this, we abstract it away here.

Parameters
string$tableThe table we should update.
array$keysThe key columns.
array$dataAssociative array with columns.

Definition at line 212 of file SQL.php.

213 {
214 assert(is_string($table));
215
216 $colNames = '('.implode(', ', array_keys($data)).')';
217 $values = 'VALUES(:'.implode(', :', array_keys($data)).')';
218
219 switch ($this->driver) {
220 case 'mysql':
221 $query = 'REPLACE INTO '.$table.' '.$colNames.' '.$values;
222 $query = $this->pdo->prepare($query);
223 $query->execute($data);
224 return;
225 case 'sqlite':
226 $query = 'INSERT OR REPLACE INTO '.$table.' '.$colNames.' '.$values;
227 $query = $this->pdo->prepare($query);
228 $query->execute($data);
229 return;
230 }
231
232 // default implementation, try INSERT, and UPDATE if that fails.
233 $insertQuery = 'INSERT INTO '.$table.' '.$colNames.' '.$values;
234 $insertQuery = $this->pdo->prepare($insertQuery);
235 try {
236 $insertQuery->execute($data);
237 return;
238 } catch (\PDOException $e) {
239 $ecode = (string) $e->getCode();
240 switch ($ecode) {
241 case '23505': // PostgreSQL
242 break;
243 default:
244 Logger::error('Error while saving data: '.$e->getMessage());
245 throw $e;
246 }
247 }
248
249 $updateCols = array();
250 $condCols = array();
251 foreach ($data as $col => $value) {
252 $tmp = $col.' = :'.$col;
253
254 if (in_array($col, $keys, true)) {
255 $condCols[] = $tmp;
256 } else {
257 $updateCols[] = $tmp;
258 }
259 }
260
261 $updateQuery = 'UPDATE '.$table.' SET '.implode(',', $updateCols).' WHERE '.implode(' AND ', $condCols);
262 $updateQuery = $this->pdo->prepare($updateQuery);
263 $updateQuery->execute($data);
264 }
static error($string)
Definition: Logger.php:166
$keys
if(empty($password)) $table
Definition: pwgen.php:24
$values

References $data, $keys, $query, $table, $values, and SimpleSAML\Logger\error().

Referenced by SimpleSAML\Store\SQL\set(), and SimpleSAML\Store\SQL\setTableVersion().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set()

SimpleSAML\Store\SQL::set (   $type,
  $key,
  $value,
  $expire = null 
)

Save a value in the data store.

Parameters
string$typeThe type of the data.
string$keyThe key to insert.
mixed$valueThe value itself.
int | null$expireThe expiration time (unix timestamp), or null if it never expires.

Reimplemented from SimpleSAML\Store.

Definition at line 333 of file SQL.php.

334 {
335 assert(is_string($type));
336 assert(is_string($key));
337 assert($expire === null || (is_int($expire) && $expire > 2592000));
338
339 if (rand(0, 1000) < 10) {
340 $this->cleanKVStore();
341 }
342
343 if (strlen($key) > 50) {
344 $key = sha1($key);
345 }
346
347 if ($expire !== null) {
348 $expire = gmdate('Y-m-d H:i:s', $expire);
349 }
350
351 $value = serialize($value);
352 $value = rawurlencode($value);
353
354 $data = array(
355 '_type' => $type,
356 '_key' => $key,
357 '_value' => $value,
358 '_expire' => $expire,
359 );
360
361 $this->insertOrUpdate($this->prefix.'_kvstore', array('_type', '_key'), $data);
362 }
insertOrUpdate($table, array $keys, array $data)
Insert or update a key-value in the store.
Definition: SQL.php:212
cleanKVStore()
Clean the key-value table of expired entries.
Definition: SQL.php:270
$expire
Definition: saml2-acs.php:140

References $data, $expire, $key, $type, SimpleSAML\Store\SQL\cleanKVStore(), and SimpleSAML\Store\SQL\insertOrUpdate().

+ Here is the call graph for this function:

◆ setTableVersion()

SimpleSAML\Store\SQL::setTableVersion (   $name,
  $version 
)

Set table version.

Parameters
string$nameTable name.
int$versionTable version.

Definition at line 189 of file SQL.php.

190 {
191 assert(is_string($name));
192 assert(is_int($version));
193
194 $this->insertOrUpdate(
195 $this->prefix.'_tableVersion',
196 array('_name'),
197 array('_name' => $name, '_version' => $version)
198 );
199 $this->tableVersions[$name] = $version;
200 }
$version
Definition: build.php:27

References $name, $version, and SimpleSAML\Store\SQL\insertOrUpdate().

Referenced by SimpleSAML\Store\SQL\initKVTable().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $driver

SimpleSAML\Store\SQL::$driver

Definition at line 29 of file SQL.php.

◆ $pdo

SimpleSAML\Store\SQL::$pdo

Definition at line 21 of file SQL.php.

◆ $prefix

SimpleSAML\Store\SQL::$prefix

Definition at line 37 of file SQL.php.

◆ $tableVersions

SimpleSAML\Store\SQL::$tableVersions
private

Definition at line 45 of file SQL.php.


The documentation for this class was generated from the following file: