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...
 
- Public Member Functions inherited from SimpleSAML\Store
 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.

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

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  }
initKVTable()
Initialize key-value table.
Definition: SQL.php:104
$config
Definition: bootstrap.php:15
foreach($paths as $path) $dsn
Definition: migrateto20.php:56
initTableVersionTable()
Initialize the table-version table.
Definition: SQL.php:81
$password
Definition: cron.php:14
+ 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.

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

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

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
+ 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.

Definition at line 371 of file SQL.php.

References $data, $query, and $type.

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  }
$type
$query
$key
Definition: croninfo.php:18
$data
Definition: bench.php:6

◆ 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.

Definition at line 290 of file SQL.php.

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

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  }
$type
$query
$row
$key
Definition: croninfo.php:18

◆ 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.

References $name.

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

172  {
173  assert(is_string($name));
174 
175  if (!isset($this->tableVersions[$name])) {
176  return 0;
177  }
178 
179  return $this->tableVersions[$name];
180  }
+ 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.

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

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

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
$query
getTableVersion($name)
Get table version.
Definition: SQL.php:171
+ 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.

References $row.

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

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  }
$row
+ 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.

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

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

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  }
$keys
$values
static error($string)
Definition: Logger.php:166
$query
if(empty($password)) $table
Definition: pwgen.php:24
$data
Definition: bench.php:6
+ 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.

Definition at line 333 of file SQL.php.

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

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  }
$expire
Definition: saml2-acs.php:140
$type
cleanKVStore()
Clean the key-value table of expired entries.
Definition: SQL.php:270
insertOrUpdate($table, array $keys, array $data)
Insert or update a key-value in the store.
Definition: SQL.php:212
$key
Definition: croninfo.php:18
$data
Definition: bench.php:6
+ 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.

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

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

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
insertOrUpdate($table, array $keys, array $data)
Insert or update a key-value in the store.
Definition: SQL.php:212
+ 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: