class DB_storage in Flickr API 5
Provides an object interface to a table row
It lets you add, delete and change rows using objects rather than SQL statements.
@category Database @package DB @author Stig Bakken <stig@php.net> @copyright 1997-2005 The PHP Group @license http://www.php.net/license/3_0.txt PHP License 3.0 @version Release: @package_version@ @link http://pear.php.net/package/DB
Hierarchy
- class \PEAR
- class \DB_storage
Expanded class hierarchy of DB_storage
File
- phpFlickr/
PEAR/ DB/ storage.php, line 43
View source
class DB_storage extends PEAR {
// {{{ properties
/** the name of the table (or view, if the backend database supports
updates in views) we hold data from */
var $_table = null;
/** which column(s) in the table contains primary keys, can be a
string for single-column primary keys, or an array of strings
for multiple-column primary keys */
var $_keycolumn = null;
/** DB connection handle used for all transactions */
var $_dbh = null;
/** an assoc with the names of database fields stored as properties
in this object */
var $_properties = [];
/** an assoc with the names of the properties in this object that
have been changed since they were fetched from the database */
var $_changes = [];
/** flag that decides if data in this object can be changed.
objects that don't have their table's key column in their
property lists will be flagged as read-only. */
var $_readonly = false;
/** function or method that implements a validator for fields that
are set, this validator function returns true if the field is
valid, false if not */
var $_validator = null;
// }}}
// {{{ constructor
/**
* Constructor
*
* @param $table string the name of the database table
*
* @param $keycolumn mixed string with name of key column, or array of
* strings if the table has a primary key of more than one column
*
* @param $dbh object database connection object
*
* @param $validator mixed function or method used to validate
* each new value, called with three parameters: the name of the
* field/column that is changing, a reference to the new value and
* a reference to this object
*
*/
function DB_storage($table, $keycolumn, &$dbh, $validator = null) {
$this
->PEAR('DB_Error');
$this->_table = $table;
$this->_keycolumn = $keycolumn;
$this->_dbh = $dbh;
$this->_readonly = false;
$this->_validator = $validator;
}
// }}}
// {{{ _makeWhere()
/**
* Utility method to build a "WHERE" clause to locate ourselves in
* the table.
*
* XXX future improvement: use rowids?
*
* @access private
*/
function _makeWhere($keyval = null) {
if (is_array($this->_keycolumn)) {
if ($keyval === null) {
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
$keyval[] = $this->{$this->_keycolumn[$i]};
}
}
$whereclause = '';
for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
if ($i > 0) {
$whereclause .= ' AND ';
}
$whereclause .= $this->_keycolumn[$i];
if (is_null($keyval[$i])) {
// there's not much point in having a NULL key,
// but we support it anyway
$whereclause .= ' IS NULL';
}
else {
$whereclause .= ' = ' . $this->_dbh
->quote($keyval[$i]);
}
}
}
else {
if ($keyval === null) {
$keyval = @$this->{$this->_keycolumn};
}
$whereclause = $this->_keycolumn;
if (is_null($keyval)) {
// there's not much point in having a NULL key,
// but we support it anyway
$whereclause .= ' IS NULL';
}
else {
$whereclause .= ' = ' . $this->_dbh
->quote($keyval);
}
}
return $whereclause;
}
// }}}
// {{{ setup()
/**
* Method used to initialize a DB_storage object from the
* configured table.
*
* @param $keyval mixed the key[s] of the row to fetch (string or array)
*
* @return int DB_OK on success, a DB error if not
*/
function setup($keyval) {
$whereclause = $this
->_makeWhere($keyval);
$query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause;
$sth = $this->_dbh
->query($query);
if (DB::isError($sth)) {
return $sth;
}
$row = $sth
->fetchRow(DB_FETCHMODE_ASSOC);
if (DB::isError($row)) {
return $row;
}
if (!$row) {
return $this
->raiseError(null, DB_ERROR_NOT_FOUND, null, null, $query, null, true);
}
foreach ($row as $key => $value) {
$this->_properties[$key] = true;
$this->{$key} = $value;
}
return DB_OK;
}
// }}}
// {{{ insert()
/**
* Create a new (empty) row in the configured table for this
* object.
*/
function insert($newpk) {
if (is_array($this->_keycolumn)) {
$primarykey = $this->_keycolumn;
}
else {
$primarykey = array(
$this->_keycolumn,
);
}
settype($newpk, "array");
for ($i = 0; $i < sizeof($primarykey); $i++) {
$pkvals[] = $this->_dbh
->quote($newpk[$i]);
}
$sth = $this->_dbh
->query("INSERT INTO {$this->_table} (" . implode(",", $primarykey) . ") VALUES(" . implode(",", $pkvals) . ")");
if (DB::isError($sth)) {
return $sth;
}
if (sizeof($newpk) == 1) {
$newpk = $newpk[0];
}
$this
->setup($newpk);
}
// }}}
// {{{ toString()
/**
* Output a simple description of this DB_storage object.
* @return string object description
*/
function toString() {
$info = strtolower(get_class($this));
$info .= " (table=";
$info .= $this->_table;
$info .= ", keycolumn=";
if (is_array($this->_keycolumn)) {
$info .= "(" . implode(",", $this->_keycolumn) . ")";
}
else {
$info .= $this->_keycolumn;
}
$info .= ", dbh=";
if (is_object($this->_dbh)) {
$info .= $this->_dbh
->toString();
}
else {
$info .= "null";
}
$info .= ")";
if (sizeof($this->_properties)) {
$info .= " [loaded, key=";
$keyname = $this->_keycolumn;
if (is_array($keyname)) {
$info .= "(";
for ($i = 0; $i < sizeof($keyname); $i++) {
if ($i > 0) {
$info .= ",";
}
$info .= $this->{$keyname[$i]};
}
$info .= ")";
}
else {
$info .= $this->{$keyname};
}
$info .= "]";
}
if (sizeof($this->_changes)) {
$info .= " [modified]";
}
return $info;
}
// }}}
// {{{ dump()
/**
* Dump the contents of this object to "standard output".
*/
function dump() {
foreach ($this->_properties as $prop => $foo) {
print "{$prop} = ";
print htmlentities($this->{$prop});
print "<br />\n";
}
}
// }}}
// {{{ &create()
/**
* Static method used to create new DB storage objects.
* @param $data assoc. array where the keys are the names
* of properties/columns
* @return object a new instance of DB_storage or a subclass of it
*/
function &create($table, &$data) {
$classname = strtolower(get_class($this));
$obj =& new $classname($table);
foreach ($data as $name => $value) {
$obj->_properties[$name] = true;
$obj->{$name} =& $value;
}
return $obj;
}
// }}}
// {{{ loadFromQuery()
/**
* Loads data into this object from the given query. If this
* object already contains table data, changes will be saved and
* the object re-initialized first.
*
* @param $query SQL query
*
* @param $params parameter list in case you want to use
* prepare/execute mode
*
* @return int DB_OK on success, DB_WARNING_READ_ONLY if the
* returned object is read-only (because the object's specified
* key column was not found among the columns returned by $query),
* or another DB error code in case of errors.
*/
// XXX commented out for now
/*
function loadFromQuery($query, $params = null)
{
if (sizeof($this->_properties)) {
if (sizeof($this->_changes)) {
$this->store();
$this->_changes = array();
}
$this->_properties = array();
}
$rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params);
if (DB::isError($rowdata)) {
return $rowdata;
}
reset($rowdata);
$found_keycolumn = false;
while (list($key, $value) = each($rowdata)) {
if ($key == $this->_keycolumn) {
$found_keycolumn = true;
}
$this->_properties[$key] = true;
$this->$key = &$value;
unset($value); // have to unset, or all properties will
// refer to the same value
}
if (!$found_keycolumn) {
$this->_readonly = true;
return DB_WARNING_READ_ONLY;
}
return DB_OK;
}
*/
// }}}
// {{{ set()
/**
* Modify an attriute value.
*/
function set($property, $newvalue) {
// only change if $property is known and object is not
// read-only
if ($this->_readonly) {
return $this
->raiseError(null, DB_WARNING_READ_ONLY, null, null, null, null, true);
}
if (@isset($this->_properties[$property])) {
if (empty($this->_validator)) {
$valid = true;
}
else {
$valid = @call_user_func($this->_validator, $this->_table, $property, $newvalue, $this->{$property}, $this);
}
if ($valid) {
$this->{$property} = $newvalue;
if (empty($this->_changes[$property])) {
$this->_changes[$property] = 0;
}
else {
$this->_changes[$property]++;
}
}
else {
return $this
->raiseError(null, DB_ERROR_INVALID, null, null, "invalid field: {$property}", null, true);
}
return true;
}
return $this
->raiseError(null, DB_ERROR_NOSUCHFIELD, null, null, "unknown field: {$property}", null, true);
}
// }}}
// {{{ &get()
/**
* Fetch an attribute value.
*
* @param string attribute name
*
* @return attribute contents, or null if the attribute name is
* unknown
*/
function &get($property) {
// only return if $property is known
if (isset($this->_properties[$property])) {
return $this->{$property};
}
$tmp = null;
return $tmp;
}
// }}}
// {{{ _DB_storage()
/**
* Destructor, calls DB_storage::store() if there are changes
* that are to be kept.
*/
function _DB_storage() {
if (sizeof($this->_changes)) {
$this
->store();
}
$this->_properties = array();
$this->_changes = array();
$this->_table = null;
}
// }}}
// {{{ store()
/**
* Stores changes to this object in the database.
*
* @return DB_OK or a DB error
*/
function store() {
foreach ($this->_changes as $name => $foo) {
$params[] =& $this->{$name};
$vars[] = $name . ' = ?';
}
if ($vars) {
$query = 'UPDATE ' . $this->_table . ' SET ' . implode(', ', $vars) . ' WHERE ' . $this
->_makeWhere();
$stmt = $this->_dbh
->prepare($query);
$res = $this->_dbh
->execute($stmt, $params);
if (DB::isError($res)) {
return $res;
}
$this->_changes = array();
}
return DB_OK;
}
// }}}
// {{{ remove()
/**
* Remove the row represented by this object from the database.
*
* @return mixed DB_OK or a DB error
*/
function remove() {
if ($this->_readonly) {
return $this
->raiseError(null, DB_WARNING_READ_ONLY, null, null, null, null, true);
}
$query = 'DELETE FROM ' . $this->_table . ' WHERE ' . $this
->_makeWhere();
$res = $this->_dbh
->query($query);
if (DB::isError($res)) {
return $res;
}
foreach ($this->_properties as $prop => $foo) {
unset($this->{$prop});
}
$this->_properties = array();
$this->_changes = array();
return DB_OK;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DB_storage:: |
property | an assoc with the names of the properties in this object that have been changed since they were fetched from the database | ||
DB_storage:: |
property | DB connection handle used for all transactions | ||
DB_storage:: |
property | which column(s) in the table contains primary keys, can be a string for single-column primary keys, or an array of strings for multiple-column primary keys | ||
DB_storage:: |
property | an assoc with the names of database fields stored as properties in this object | ||
DB_storage:: |
property | flag that decides if data in this object can be changed. objects that don't have their table's key column in their property lists will be flagged as read-only. | ||
DB_storage:: |
property | the name of the table (or view, if the backend database supports updates in views) we hold data from | ||
DB_storage:: |
property | function or method that implements a validator for fields that are set, this validator function returns true if the field is valid, false if not | ||
DB_storage:: |
function | Static method used to create new DB storage objects. | ||
DB_storage:: |
function | Constructor | ||
DB_storage:: |
function | Dump the contents of this object to "standard output". | ||
DB_storage:: |
function | Fetch an attribute value. | ||
DB_storage:: |
function | Create a new (empty) row in the configured table for this object. | ||
DB_storage:: |
function | Remove the row represented by this object from the database. | ||
DB_storage:: |
function | Modify an attriute value. | ||
DB_storage:: |
function | Method used to initialize a DB_storage object from the configured table. | ||
DB_storage:: |
function | Stores changes to this object in the database. | ||
DB_storage:: |
function | Output a simple description of this DB_storage object. | ||
DB_storage:: |
function | Destructor, calls DB_storage::store() if there are changes that are to be kept. | ||
DB_storage:: |
function | Utility method to build a "WHERE" clause to locate ourselves in the table. | ||
PEAR:: |
property | Whether to enable internal debug messages. | ||
PEAR:: |
property | Default error handler (callback) for this object, if error mode is PEAR_ERROR_CALLBACK. | ||
PEAR:: |
property | Default error mode for this object. | ||
PEAR:: |
property | Default error options used for this object when error mode is PEAR_ERROR_TRIGGER. | ||
PEAR:: |
property | Which class to use for error objects. | ||
PEAR:: |
property | An array of expected errors. | ||
PEAR:: |
function | This method deletes all occurences of the specified element from the expected error codes stack. | ||
PEAR:: |
function | This method is used to tell which errors you expect to get. Expected errors are always returned with error mode PEAR_ERROR_RETURN. Expected error codes are stored in a stack, and this method pushes a new element onto it. The list of expected errors… | ||
PEAR:: |
function | If you have a class that's mostly/entirely static, and you need static properties, you can use this method to simulate them. Eg. in your method(s) do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); You MUST… | ||
PEAR:: |
function | Tell whether a value is a PEAR error. | ||
PEAR:: |
function | OS independant PHP extension load. Remember to take care on the correct extension name for case sensitive OSes. | ||
PEAR:: |
function | Constructor. Registers this object in $_PEAR_destructor_object_list for destructor emulation if a destructor object exists. | ||
PEAR:: |
function | Pop the last error handler used | ||
PEAR:: |
function | This method pops one element off the expected error codes stack. | ||
PEAR:: |
function | Push a new error handler on top of the error handler options stack. With this you can easily override the actual error handler for some code and restore it later with popErrorHandling. | ||
PEAR:: |
function | This method is a wrapper that returns an instance of the configured error class with this object's default error handling applied. If the $mode and $options parameters are not specified, the object's defaults are used. | 1 | |
PEAR:: |
function | Use this function to register a shutdown method for static classes. | ||
PEAR:: |
function | Sets how errors generated by this object should be handled. Can be invoked both in objects and statically. If called statically, setErrorHandling sets the default behaviour for all PEAR objects. If called in an object, setErrorHandling sets the… | ||
PEAR:: |
function | |||
PEAR:: |
function | |||
PEAR:: |
function | Simpler form of raiseError with fewer options. In most cases message, code and userinfo are enough. | ||
PEAR:: |
function | This method checks unsets an error code if available | ||
PEAR:: |
function | Destructor (the emulated type of...). Does nothing right now, but is included for forward compatibility, so subclass destructors should always call it. |