From 537583a23167760cbe8037fc179b0550d0fa2187 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 19 Dec 2011 12:00:08 +0000 Subject: [PATCH] Add DatabaseObject base class DatabaseObject exposes common behaviours for database table wrapper classes. --- source/lib/SihnonFramework/Database.class.php | 4 +- .../SihnonFramework/DatabaseObject.class.php | 212 ++++++++++++++++++ .../lib/SihnonFramework/Exceptions.class.php | 1 + 3 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 source/lib/SihnonFramework/DatabaseObject.class.php diff --git a/source/lib/SihnonFramework/Database.class.php b/source/lib/SihnonFramework/Database.class.php index 9de43f6..57f596c 100644 --- a/source/lib/SihnonFramework/Database.class.php +++ b/source/lib/SihnonFramework/Database.class.php @@ -68,7 +68,7 @@ class SihnonFramework_Database { } private function query($sql, $count = 0) { - $results = $this->dbh->query($sql); + $results = $this->dbh->query($sql, PDO::FETCH_ASSOC); if (! $results) { list($std_code, $driver_code, $message) = $this->dbh->errorInfo(); @@ -123,7 +123,7 @@ class SihnonFramework_Database { } } - return $stmt->fetchAll(); + return $stmt->fetchAll(PDO::FETCH_ASSOC); } else { $results = array(); diff --git a/source/lib/SihnonFramework/DatabaseObject.class.php b/source/lib/SihnonFramework/DatabaseObject.class.php new file mode 100644 index 0000000..1679390 --- /dev/null +++ b/source/lib/SihnonFramework/DatabaseObject.class.php @@ -0,0 +1,212 @@ + $value) { + if (property_exists(get_called_class(), '_db_' . $property)) { + $this->{'_db_' . $property} = $value; + } else { + throw new Sihnon_Exception_InvalidProperty($property); + } + } + } + + public static function fromDatabaseRow($row) { + $object = new static(); + $object->setDatabaseProperties($row); + + return $object; + } + + /** + * Load a DatabaseObject given its ID + * + * @param int $id + * @return SihnonFramework_DatabaseObject + */ + public static function fromId($id) { + $database = SihnonFramework_Main::instance()->database(); + + $object = self::fromDatabaseRow( + $database->selectOne('SELECT * FROM `'.static::table().'` WHERE id=:id', array( + array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT) + ) + ) + ); + + return $object; + } + + /** + * Load a DatabaseObject given a field name and value + * + * @param string $name Name of the field to match on + * @param mixed $value Value of the field to match on + */ + public static function from($field, $value) { + $database = SihnonFramework_Main::instance()->database(); + + $object = self::fromDatabaseRow( + $database->selectOne("SELECT * FROM `".static::table()."` WHERE `{$field}`=:{$field}", array( + array('name' => $field, 'value' => $value, 'type' => PDO::PARAM_STR) + ) + ) + ); + + return $object; + } + + /** + * Load a list of all objects + * + * @return SihnonFramework_DatabaseObject + */ + public static function all() { + $database = SihnonFramework_Main::instance()->database(); + + $objects = array(); + foreach ($database->selectList('SELECT * FROM `'.static::table().'` WHERE `id` > 0 ORDER BY `id` DESC') as $row) { + $objects[] = static::fromDatabaseRow($row); + } + + return $objects; + } + + public static function all_for($field, $value, $view = null) { + $database = SihnonFramework_Main::instance()->database(); + + if ($view === null) { + $view = static::table(); + } + + $class = new ReflectionClass(get_called_class()); + $properties = $class->getproperties(); + + $fields = array(); + foreach ($properties as $property) { + $matches = array(); + if (preg_match('/^_db_(.*)/', $property->name, $matches)) { + $fields[] = $matches[1]; + } + } + + $field_list = join(', ', array_map(function($v) { return "`{$v}`"; }, $fields));$objects = array(); + + foreach ($database->selectList("SELECT {$field_list} FROM `{$view}` WHERE `{$field}`=:{$field} ORDER BY `id` DESC", array( + array('name' => $field, 'value' => $value, 'type' => PDO::PARAM_STR), + )) as $row) { + $objects[] = static::fromDatabaseRow($row); + } + + return $objects; + } + + public static function exists($field, $value, $view = null) { + $database = Sihnon_Main::instance()->database(); + + return $database->selectOne('SELECT COUNT(*) FROM `'.static::table().'` "WHERE `{$field}`=:{$field} LIMIT 1', array( + array('name' => $field, 'value' => $value, 'type' => PDO::PARAM_STR), + ) + ); + } + + protected function create() { + $database = SihnonFramework_Main::instance()->database(); + + $class = new ReflectionClass(get_called_class()); + $properties = $class->getproperties(); + + $fields = array(); + $params = array(); + foreach ($properties as $property) { + $matches = array(); + if (preg_match('/^_db_(.*)/', $property->name, $matches)) { + $fields[] = $matches[1]; + + $params[] = array( + 'name' => $matches[1], + 'value' => ($matches[1] == 'id') ? 'NULL' : $this->{"_db_{$matches[1]}"}, + 'type' => PDO::PARAM_STR + ); + } + } + + $id_list = join(', ', array_map(function($v) { return "`{$v}`"; }, $fields)); + $value_list = join(', ', array_map(function($v) { return ":{$v}"; }, $fields)); + + $database->insert('INSERT INTO `'.static::table().'` ({$id_list}) VALUES({$value_list})', $params); + + $this->id = $database->lastInsertId(); + } + + protected function save() { + $database = SihnonFramework_Main::instance()->database(); + + $class = new ReflectionClass(get_called_class()); + $properties = $class->getproperties(); + + $fields = array(); + $params = array(); + foreach ($properties as $property) { + $matches = array(); + if (preg_match('/^_db_(.*)/', $property->name, $matches)) { + if ($matches[1] != 'id') { + $fields[] = $matches[1]; + } + + $params[] = array( + 'name' => $matches[1], + 'value' => $this->{"_db_{$matches[1]}"}, + 'type' => PDO::PARAM_STR + ); + } + } + + $id_list = join(', ', array_map(function($v) { return "`{$v}`"; }, $fields)); + $value_list = join(', ', array_map(function($v) { return ":{$v}"; }, $fields)); + + $database->update('UPDATE `'.static::table().'` ({$id_list}) VALUES({$value_list}) WHERE `id`=:id', $params); + } + + public function delete() { + $database = SihnonFramework_Main::instance()->database(); + + $database->update( + 'DELETE FROM `'.static::table().'` WHERE `id`=:id LIMIT 1', + array( + array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT), + ) + ); + + $this->id = null; + } + + public function __set($name, $value) { + $fullname = "_db_{$name}"; + if ( ! property_exists(get_called_class(), $fullname)){ + throw new SihnonFramework_Exception_InvalidProperty($name); + } + + $this->{$fullname} = $value; + } + + public function __get($name) { + $fullname = "_db_{$name}"; + if ( ! property_exists(get_called_class(), $fullname)){ + throw new SihnonFramework_Exception_InvalidProperty($name); + } + + return $this->{$fullname}; + } + + +} + +?> \ No newline at end of file diff --git a/source/lib/SihnonFramework/Exceptions.class.php b/source/lib/SihnonFramework/Exceptions.class.php index 0ce68c0..d17205d 100644 --- a/source/lib/SihnonFramework/Exceptions.class.php +++ b/source/lib/SihnonFramework/Exceptions.class.php @@ -21,6 +21,7 @@ class SihnonFramework_Exception_DatabaseConnectFailed extends SihnonFramework_E class SihnonFramework_Exception_NoDatabaseConnection extends SihnonFramework_Exception_DatabaseException {}; class SihnonFramework_Exception_DatabaseQueryFailed extends SihnonFramework_Exception_DatabaseException {}; class SihnonFramework_Exception_ResultCountMismatch extends SihnonFramework_Exception_DatabaseException {}; +class SihnonFramework_Exception_InvalidProperty extends SihnonFramework_Exception_DatabaseException {}; class SihnonFramework_Exception_ConfigException extends SihnonFramework_Exception {}; class SihnonFramework_Exception_UnknownSetting extends SihnonFramework_Exception_ConfigException {};