6 use \SimpleSAML\Logger;
53 $config = Configuration::getInstance();
56 $username =
$config->getString(
'store.sql.username', null);
59 $this->prefix =
$config->getString(
'store.sql.prefix',
'simpleSAMLphp');
63 throw new \Exception(
"Database error: " . $e->getMessage());
65 $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
67 $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
69 if ($this->driver ===
'mysql') {
70 $this->pdo->exec(
'SET time_zone = "+00:00"');
83 $this->tableVersions = array();
86 $fetchTableVersion = $this->pdo->query(
'SELECT _name, _version FROM '.$this->prefix.
'_tableVersion');
89 'CREATE TABLE '.$this->prefix.
90 '_tableVersion (_name VARCHAR(30) NOT NULL UNIQUE, _version INTEGER NOT NULL)' 95 while ((
$row = $fetchTableVersion->fetch(\PDO::FETCH_ASSOC)) !==
false) {
96 $this->tableVersions[
$row[
'_name']] = (int) $row[
'_version'];
109 if ($this->driver ===
'mysql') {
111 $text_t =
'LONGTEXT';
118 $table_updates = 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)' 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)' 145 $latest_version = count($table_updates);
147 if ($current_version == $latest_version) {
152 $updates_to_run = array_slice($table_updates, $current_version);
154 foreach ($updates_to_run as $version_updates) {
155 foreach ($version_updates as
$query) {
156 $this->pdo->exec($query);
173 assert(is_string(
$name));
175 if (!isset($this->tableVersions[
$name])) {
179 return $this->tableVersions[
$name];
191 assert(is_string(
$name));
195 $this->prefix.
'_tableVersion',
214 assert(is_string(
$table));
216 $colNames =
'('.implode(
', ', array_keys($data)).
')';
217 $values =
'VALUES(:'.implode(
', :', array_keys($data)).
')';
219 switch ($this->driver) {
226 $query =
'INSERT OR REPLACE INTO '.$table.
' '.$colNames.
' '.
$values;
233 $insertQuery =
'INSERT INTO '.$table.
' '.$colNames.
' '.
$values;
234 $insertQuery = $this->pdo->prepare($insertQuery);
236 $insertQuery->execute($data);
239 $ecode = (string) $e->getCode();
249 $updateCols = array();
251 foreach ($data as $col => $value) {
252 $tmp = $col.
' = :'.$col;
254 if (in_array($col, $keys,
true)) {
257 $updateCols[] = $tmp;
261 $updateQuery =
'UPDATE '.$table.
' SET '.implode(
',', $updateCols).
' WHERE '.implode(
' AND ', $condCols);
262 $updateQuery = $this->pdo->prepare($updateQuery);
263 $updateQuery->execute($data);
274 $query =
'DELETE FROM '.$this->prefix.
'_kvstore WHERE _expire < :now';
275 $params = array(
'now' => gmdate(
'Y-m-d H:i:s'));
292 assert(is_string(
$type));
293 assert(is_string(
$key));
295 if (strlen(
$key) > 50) {
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'));
307 if (
$row ===
false) {
311 $value =
$row[
'_value'];
312 if (is_resource($value)) {
313 $value = stream_get_contents($value);
315 $value = urldecode($value);
316 $value = unserialize($value);
318 if ($value ===
false) {
335 assert(is_string(
$type));
336 assert(is_string($key));
337 assert($expire === null || (is_int($expire) && $expire > 2592000));
339 if (rand(0, 1000) < 10) {
343 if (strlen($key) > 50) {
347 if ($expire !== null) {
348 $expire = gmdate(
'Y-m-d H:i:s', $expire);
351 $value = serialize($value);
352 $value = rawurlencode($value);
358 '_expire' => $expire,
373 assert(is_string(
$type));
374 assert(is_string($key));
376 if (strlen($key) > 50) {
385 $query =
'DELETE FROM '.$this->prefix.
'_kvstore WHERE _type=:_type AND _key=:_key';
initKVTable()
Initialize key-value table.
setTableVersion($name, $version)
Set table version.
foreach($paths as $path) $dsn
initTableVersionTable()
Initialize the table-version table.
cleanKVStore()
Clean the key-value table of expired entries.
insertOrUpdate($table, array $keys, array $data)
Insert or update a key-value in the store.
getTableVersion($name)
Get table version.
__construct()
Initialize the SQL data store.
if(empty($password)) $table