From 89e6830e08b47a2992dad6885544795a6c866708 Mon Sep 17 00:00:00 2001 From: Etenil Date: Sat, 9 Jul 2011 21:23:23 +0100 Subject: [PATCH] Implemented Session on Storage, refactored drivers for Storage. --- .gitignore => .bzrignore | 0 loader.php | 1 + system/Session.php | 89 ++++++++++--------- system/Storage/StorageEngineWrapper.php | 70 +++++++++++++++ .../{sqlite => }/StorageEngineSqlite.php | 30 +++++-- system/Storage/drivers/sqlite/init.php | 5 -- system/Storage/loader.php | 15 +++- tests/php/Session/TestSession.php | 36 +++++++- tests/php/run-tests.php | 2 +- 9 files changed, 190 insertions(+), 58 deletions(-) rename .gitignore => .bzrignore (100%) create mode 100644 system/Storage/StorageEngineWrapper.php rename system/Storage/drivers/{sqlite => }/StorageEngineSqlite.php (93%) delete mode 100644 system/Storage/drivers/sqlite/init.php diff --git a/.gitignore b/.bzrignore similarity index 100% rename from .gitignore rename to .bzrignore diff --git a/loader.php b/loader.php index 98678daa4..8e7a16955 100644 --- a/loader.php +++ b/loader.php @@ -38,6 +38,7 @@ require(LIB_PATH . "Widget/WidgetWrapper.php"); // Starting session. +storage_load_driver('sqlite'); Session::start(APP_NAME); ?> diff --git a/system/Session.php b/system/Session.php index 08aab59ee..9617f3d81 100644 --- a/system/Session.php +++ b/system/Session.php @@ -26,22 +26,25 @@ class SessionVar extends StorageBase protected $name; protected $value; protected $session; + protected $container; + protected $timestamp; protected function type_init() { - $this->name = StorageType::varchar(128); - $this->value = StorageType::text(); - $this->session = StorageType::varchar(128); + $this->name = StorageType::varchar(128); + $this->value = StorageType::text(); + $this->session = StorageType::varchar(128); + $this->container = StorageType::varchar(128); + $this->timestamp = StorageType::int(); } } - + class Session { protected $db; protected static $instances = array(); protected static $sid = null; protected $container; - protected $container_id; protected $max_age = 3600; /** @@ -52,17 +55,20 @@ class Session { $db_file = (($_SERVER['DOCUMENT_ROOT'] == "")? dirname(__FILE__) : $_SERVER['DOCUMENT_ROOT']).'/session.db'; - if(defined('SESSION_DB_FILE')) { + if(defined('TEST_DB_FILE')) { + $db_file = TEST_DB_FILE; + } else if(defined('SESSION_DB_FILE')) { $db_file = SESSION_DB_FILE; } if(defined('SESSION_MAX_AGE')) { $this->max_age = SESSION_MAX_AGE; } - + // Do we create the schema? $create = false; - if(!file_exists($db_file)) { + if(defined('SESSION_FORCE_CREATE') + || !file_exists($db_file)) { $create = true; } @@ -73,7 +79,15 @@ class Session $this->db->create($var); } - $this->regenerate(); + if(self::$sid == null) { + if(isset($_COOKIE['PHPFASTSESSID'])) { + self::$sid = $_COOKIE['PHPFASTSESSID']; + } else { + $this->regenerate(); + } + } + + $this->container = $name; } protected function regenerate() @@ -103,24 +117,17 @@ class Session return self::$instances[$name]; } - /** - * Commits the session upon destruction. - */ -/* public function __destruct() - { - $this->db->close(); - }*/ - /** * Gets a session variable. Returns false if doesn't exist. */ public function get($varname) { - $data = $this->db->querySingle( - 'SELECT * FROM session_vars WHERE container="'.$this->container_id.'" AND name="'.$this->db->escapeString($varname).'"', - true); - if(count($data) > 0) { - return unserialize(base64_decode($data['value'])); + $data = new SessionVar(); + if($this->db->load($data, array( + 'session' => self::$sid, + 'container' => $this->container, + 'name' => $varname))) { + return unserialize(base64_decode($data->value)); } else { return false; } @@ -131,26 +138,21 @@ class Session */ public function set($varname, $value) { - $value = base64_encode(serialize($value)); - // Does the variable exist? - $sql = 'SELECT COUNT(name) FROM session_vars '. - 'WHERE container="'.$this->container_id.'" AND name="'.$varname.'"'; - $num_vars = $this->db->querySingle($sql); - - if($num_vars > 0) { - $sql = 'UPDATE session_vars '. - 'SET value="'.$this->db->escapeString($value).'" '. - 'WHERE container="'.$this->container_id.'" AND name="'.$varname.'"'; - } else { - $sql = 'INSERT INTO session_vars(container, name, value) '. - 'VALUES("'.$this->container_id.'", "'.$this->db->escapeString($varname).'", "'. - $this->db->escapeString($value).'")'; + $var = new SessionVar(); + if(!$this->db->load($var, array( + 'session' => self::$sid, + 'container' => $this->container, + 'name' => $varname))) { + $var->session = self::$sid; + $var->container = $this->container; + $var->name = $varname; } - $this->db->exec($sql); + $var->value = base64_encode(serialize($value)); + $this->db->save($var); - return $value; + return $var->value; } /** @@ -158,10 +160,13 @@ class Session */ public function remove($varname) { - return $this->db->exec( - 'DELETE FROM session_vars '. - 'WHERE container="'.$this->container_id.'" '. - 'AND name="'.$this->db->escapeString($varname).'"'); + $var = new SessionVar(); + $this->db->load($var, array( + 'session' => self::$sid, + 'container' => $this->container, + 'name' => $varname)); + + $this->db->delete($var); } public function delete_container() diff --git a/system/Storage/StorageEngineWrapper.php b/system/Storage/StorageEngineWrapper.php new file mode 100644 index 000000000..7c57d9e59 --- /dev/null +++ b/system/Storage/StorageEngineWrapper.php @@ -0,0 +1,70 @@ +driver; + $this->db = new $driver(); + call_user_func_array(array($this->db, 'init'), func_get_args()); + } + + public static function setdriver($name) + { + if(self::$driver != null) { + throw new StorageException("A storage driver is already loaded."); + } else { + $drivername = "StorageEngine".ucfirst(strtolower($name)); + // Is it loaded? + if(!class_exists($drivername)) { + storage_load($name); + } + $this->driver = $drivername; + } + } + + /* Alright now the rest of it is only aliases functions that are redirected + through the loaded driver. + + Note that call_user_func...() will _NOT_ work here. This is because PHP + doesn't pass arguments to callbacks by reference, so forget it. + */ + function create(&$object) + { + return $this->db->create($object); + } + + function save(&$object) + { + return $this->db->save($object); + } + + function delete(&$object) + { + return $this->db->delete($object); + } + + function drop(&$object) + { + return $this->db->drop(&$object); + } + + function load(&$object, array $cond) + { + return $this->db->load(&$object, $cond); + } + + function select($objecttype, array $cond) + { + return $this->db->select($objecttype, $cond); + } +} + +?> diff --git a/system/Storage/drivers/sqlite/StorageEngineSqlite.php b/system/Storage/drivers/StorageEngineSqlite.php similarity index 93% rename from system/Storage/drivers/sqlite/StorageEngineSqlite.php rename to system/Storage/drivers/StorageEngineSqlite.php index bb9ab5175..e835af284 100644 --- a/system/Storage/drivers/sqlite/StorageEngineSqlite.php +++ b/system/Storage/drivers/StorageEngineSqlite.php @@ -21,7 +21,15 @@ class StorageEngineSqlite extends StorageEngineBase implements StorageDriver protected $db; // Loading config and attempting to connect. - public function __construct($db_file) + public function __construct() + { + $args = func_get_args(); + if(count($args) > 0) { + call_user_func_array(array($this, 'init'), $args); + } + } + + public function init($db_file) { // Checking the file can be accessed. if($db_file == "") { @@ -236,8 +244,8 @@ class StorageEngineSqlite extends StorageEngineBase implements StorageDriver { $stmt = "SELECT * FROM " . $this->obj_name($object); - if(count($cond) > 1) { - $where . " WHERE "; + if(count($cond) > 0) { + $stmt.= " WHERE "; foreach($cond as $col => $val) { $stmt.= "$col=\"$val\" AND "; @@ -250,6 +258,11 @@ class StorageEngineSqlite extends StorageEngineBase implements StorageDriver $this->log($stmt); $data = $this->query($stmt); + + if(count($data) < 1) { + return false; + } + $data = $data[0]; // Populating the object. @@ -260,6 +273,8 @@ class StorageEngineSqlite extends StorageEngineBase implements StorageDriver $object->__set($prop['name'], $data[$prop['name']]); } } + + return true; } /** @@ -269,8 +284,8 @@ class StorageEngineSqlite extends StorageEngineBase implements StorageDriver { $stmt = "SELECT * FROM " . $objecttype; - if(count($cond) > 1) { - $where . " WHERE "; + if(count($cond) > 0) { + $stmt.= " WHERE "; foreach($cond as $col => $val) { $stmt.= "$col=\"$val\" AND "; @@ -283,6 +298,11 @@ class StorageEngineSqlite extends StorageEngineBase implements StorageDriver $this->log($stmt); $data = $this->query($stmt); + + if(count($data) < 1) { + return false; + } + $objs = array(); foreach($data as $row) { diff --git a/system/Storage/drivers/sqlite/init.php b/system/Storage/drivers/sqlite/init.php deleted file mode 100644 index e33364b7c..000000000 --- a/system/Storage/drivers/sqlite/init.php +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/system/Storage/loader.php b/system/Storage/loader.php index 41b21be60..96146293c 100644 --- a/system/Storage/loader.php +++ b/system/Storage/loader.php @@ -3,7 +3,7 @@ * @file loader.php * * This file is part of MOVIM. - * + * * @brief Loads up classes and stuff for Storage. * * @author Guillaume Pasquet @@ -12,23 +12,30 @@ * @date 1 June 2011 * * Copyright (C)2011 MOVIM Project - * + * * All rights reserved, see COPYING for licensing information. */ +// Function to easily load a Storage Engine. +function storage_load_driver($drivername) +{ + require($base."drivers/StorageEngine".ucfirst(strtolower($drivername)).".php"); +} + function load_storage(array $drivers) { $base = dirname(__FILE__).'/'; - + require($base.'StorageBase.php'); require($base.'StorageCollection.php'); require($base.'StorageDriver.php'); require($base.'StorageEngineBase.php'); + require($base.'StorageEngineWrapper.php'); require($base.'StorageException.php'); require($base.'StorageSchema.php'); require($base.'StorageTypeBase.php'); require($base.'StorageType.php'); - + // Now loading the drivers. foreach($drivers as $driver) { $driver_init = $base.'drivers/'.$driver.'/init.php'; diff --git a/tests/php/Session/TestSession.php b/tests/php/Session/TestSession.php index 36bcd9e8f..7f76fbd0a 100644 --- a/tests/php/Session/TestSession.php +++ b/tests/php/Session/TestSession.php @@ -20,9 +20,43 @@ define('DB_LOGFILE', 'queries.log'); class TestSession { - function testCreate() + private $db_file; + private $db; + + function __construct() { + $this->db_file = ut_res('session.db'); + define('TEST_DB_FILE', $this->db_file); + define('SESSION_FORCE_CREATE', true); + $this->_wipe(); + } + + private function _wipe() + { + if(isset($this->db)) + unset($this->db); + + unlink($this->db_file); + $this->db = new SQLite3($this->db_file); + } + + function testSession() + { + $sess = Session::start('test'); + // Checking the creation of the table. + $numtables = $this->db->querySingle('SELECT count(name) as count '. + 'FROM sqlite_master WHERE type="table" '. + 'AND name="SessionVar"'); + ut_equals($numtables, 1); + + // Inserting + $sess->set('test', 'stuff'); + $record = $this->db->querySingle( + 'SELECT value FROM SessionVar WHERE name="test"'); + ut_equals(unserialize(base64_decode($record)), 'stuff'); + $var = $sess->get('test'); + ut_equals($var, 'stuff'); } } diff --git a/tests/php/run-tests.php b/tests/php/run-tests.php index 94151b010..c4fd1363f 100755 --- a/tests/php/run-tests.php +++ b/tests/php/run-tests.php @@ -246,7 +246,7 @@ function main($argc, $argv) } if($argc == 2) - run_tests($argv[2]); + run_tests($argv[1]); else run_tests(); }