From afbfd0ef88b5af747e56351e09650a3e321a5ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=85kre=20Solberg?= <andreas.solberg@uninett.no> Date: Mon, 28 Sep 2009 09:45:06 +0000 Subject: [PATCH] Adding new functionality permanent key value store using SQLite. To be used in Oauth module and others... git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1791 44740490-163a-0410-bde0-09ae8108e29a --- config-templates/config.php | 5 +- .../core/lib/Storage/SQLPermanentStorage.php | 179 ++++++++++++++++++ 2 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 modules/core/lib/Storage/SQLPermanentStorage.php diff --git a/config-templates/config.php b/config-templates/config.php index 1da08d2a1..e6d36b97b 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -28,14 +28,15 @@ $config = array ( 'certdir' => 'cert/', 'dictionarydir' => 'dictionaries/', 'loggingdir' => 'log/', - + 'datadir' => 'data/', + /* * A directory where simpleSAMLphp can save temporary files. * * SimpleSAMLphp will attempt to create this directory if it doesn't exist. */ 'tempdir' => '/tmp/simplesaml', - + 'version' => 'trunk', /** diff --git a/modules/core/lib/Storage/SQLPermanentStorage.php b/modules/core/lib/Storage/SQLPermanentStorage.php new file mode 100644 index 000000000..d57afd6a5 --- /dev/null +++ b/modules/core/lib/Storage/SQLPermanentStorage.php @@ -0,0 +1,179 @@ +<?php + +/** + * SQLPermanentStorage + * + * Generic SQL Store to store key value pairs. To be used in several other modules that needs + * to store data permanently. + * + * @author Andreas Ă…kre Solberg <andreas@uninett.no>, UNINETT AS. + * @package simpleSAMLphp + * @version $Id$ + */ +class sspmod_core_Storage_SQLPermanentStorage { + + private $db; + + function __construct($name, $config = NULL) { + if (is_null($config)) + $config = SimpleSAML_Configuration::getInstance(); + + $datadir = $config->getPathValue('datadir'); + + if (!is_dir($datadir)) + throw new Exception('Data directory [' . $datadir. '] does not exist'); + if (!is_writable($datadir)) + throw new Exception('Data directory [' . $datadir. '] is not writable'); + + $sqllitedir = $datadir . 'sqllite/'; + if (!is_dir($sqllitedir)) { + mkdir($sqllitedir); + } + + $dbfile = $sqllitedir . $name . '.sqllite'; + + if ($this->db = new SQLiteDatabase($dbfile)) { + $q = @$this->db->query('SELECT key1 FROM data LIMIT 1'); + if ($q === false) { + $this->db->queryExec(' + CREATE TABLE data ( + key1 text, + key2 text, + type text, + value text, + created timestamp, + updated timestamp, + expire timestamp, + PRIMARY KEY (key1,key2,type) + ); + '); + } + } else { + throw new Exception('Error creating SQL lite database [' . $dbfile . '].'); + } + } + + public function set($type, $key1, $key2, $value, $duration = NULL) { + if ($this->exists($type, $key1, $key2)) { + $this->update($type, $key1, $key2, $value, $duration); + } else { + $this->insert($type, $key1, $key2, $value, $duration); + } + } + + private function insert($type, $key1, $key2, $value, $duration = NULL) { + + $setDuration = ''; + if (is_null($duration)) { + $setDuration = 'NULL'; + } else { + $setDuration = "'" . sqlite_escape_string(time() + $duration) . "'"; + } + + $query = "INSERT INTO data (key1,key2,type,created,updated,expire,value) VALUES (" . + "'" . sqlite_escape_string($key1) . "'," . + "'" . sqlite_escape_string($key2) . "'," . + "'" . sqlite_escape_string($type) . "'," . + "'" . sqlite_escape_string(time()) . "'," . + "'" . sqlite_escape_string(time()) . "'," . + $setDuration . "," . + "'" . sqlite_escape_string(serialize($value)) . "')"; + $results = $this->db->queryExec($query); + return $results; + } + + private function update($type, $key1, $key2, $value, $duration = NULL) { + + $setDuration = ''; + if (is_null($duration)) { + $setDuration = ", expire = NULL "; + } else { + $setDuration = ", expire = '" . sqlite_escape_string(time() + $duration) . "' "; + } + + $query = "UPDATE data SET " . + "updated = '" . sqlite_escape_string(time()) . "'," . + "value = '" . sqlite_escape_string(serialize($value)) . "'" . + $setDuration . + "WHERE " . + "key1 = '" . sqlite_escape_string($key1) . "' AND " . + "key2 = '" . sqlite_escape_string($key2) . "' AND " . + "type = '" . sqlite_escape_string($type) . "'"; + $results = $this->db->queryExec($query); + # echo $query; + # echo $this->db>changes; + return $results; + } + + public function get($type, $key1, $key2) { + $query = "SELECT * FROM data WHERE " . + "key1 = '" . sqlite_escape_string($key1) . "' AND " . + "key2 = '" . sqlite_escape_string($key2) . "' AND " . + "type = '" . sqlite_escape_string($type) . "'"; + $results = $this->db->arrayQuery($query, SQLITE_ASSOC); + if (count($results) !== 1) return NULL; + + $res = $results[0]; + $res['value'] = unserialize($res['value']); + return $res; + } + + public function exists($type, $key1, $key2) { + $query = "SELECT * FROM data WHERE " . + "key1 = '" . sqlite_escape_string($key1) . "' AND " . + "key2 = '" . sqlite_escape_string($key2) . "' AND " . + "type = '" . sqlite_escape_string($type) . "' LIMIT 1"; + $results = $this->db->arrayQuery($query, SQLITE_ASSOC); + return (count($results) == 1); + } + + public function getList($type = NULL, $key1 = NULL, $key2 = NULL) { + + $condition = self::getCondition($type, $key1, $key2); + $query = "SELECT * FROM data WHERE " . $condition; + $results = $this->db->arrayQuery($query, SQLITE_ASSOC); + if (count($results) == 0) return NULL; + + foreach($results AS $key => $value) { + $results[$key]['value'] = unserialize($results[$key]['value']); + } + return $results; + } + + public function remove($type, $key1, $key2) { + $query = "DELETE FROM data WHERE " . + "key1 = '" . sqlite_escape_string($key1) . "' AND " . + "key2 = '" . sqlite_escape_string($key2) . "' AND " . + "type = '" . sqlite_escape_string($type) . "'"; + $results = $this->db->arrayQuery($query, SQLITE_ASSOC); + return (count($results) == 1); + } + + public function removeExpired() { + $query = "DELETE FROM data WHERE expire NOT NULL AND expire < " . time(); + $this->db->arrayQuery($query, SQLITE_ASSOC); + $changes = $this->db>changes; + return $changes; + } + + + /** + * Create a SQL condition statement based on parameters + */ + private static function getCondition($type = NULL, $key1 = NULL, $key2 = NULL) { + $conditions = array(); + + if (!is_null($type)) $conditions[] = "type = '" . sqlite_escape_string($type) . "'"; + if (!is_null($key1)) $conditions[] = "key1 = '" . sqlite_escape_string($key1) . "'"; + if (!is_null($key2)) $conditions[] = "type = '" . sqlite_escape_string($key2) . "'"; + + if (count($conditions) === 0) return '1'; + + $condition = join(' AND ', $conditions); + + return $condition; + } + + +} + -- GitLab