[ Index ]
 

Code source de SPIP Agora 1.4

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/Pear/DB/ -> storage.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
   3  // +----------------------------------------------------------------------+
   4  // | PHP Version 4                                                        |
   5  // +----------------------------------------------------------------------+
   6  // | Copyright (c) 1997-2004 The PHP Group                                |
   7  // +----------------------------------------------------------------------+
   8  // | This source file is subject to version 2.02 of the PHP license,      |
   9  // | that is bundled with this package in the file LICENSE, and is        |
  10  // | available at through the world-wide-web at                           |
  11  // | http://www.php.net/license/2_02.txt.                                 |
  12  // | If you did not receive a copy of the PHP license and are unable to   |
  13  // | obtain it through the world-wide-web, please send a note to          |
  14  // | license@php.net so we can mail you a copy immediately.               |
  15  // +----------------------------------------------------------------------+
  16  // | Author: Stig Bakken <stig@php.net>                                   |
  17  // | Maintainer: Daniel Convissor <danielc@php.net>                       |
  18  // +----------------------------------------------------------------------+
  19  //
  20  // $Id: storage.php,v 1.17 2004/02/04 01:42:05 danielc Exp $
  21  
  22  require_once  'DB.php';
  23  
  24  /**
  25   * Provides an object interface to a table row.
  26   *
  27   * It lets you add, delete and change rows using objects rather than SQL
  28   * statements.
  29   *
  30   * @package  DB
  31   * @version  $Id: storage.php,v 1.17 2004/02/04 01:42:05 danielc Exp $
  32   * @category Database
  33   * @author   Stig Bakken <stig@php.net>
  34   */
  35  class DB_storage extends PEAR
  36  {
  37      // {{{ properties
  38  
  39      /** the name of the table (or view, if the backend database supports
  40          updates in views) we hold data from */
  41      var $_table = null;
  42  
  43      /** which column(s) in the table contains primary keys, can be a
  44          string for single-column primary keys, or an array of strings
  45          for multiple-column primary keys */
  46      var $_keycolumn = null;
  47  
  48      /** DB connection handle used for all transactions */
  49      var $_dbh = null;
  50  
  51      /** an assoc with the names of database fields stored as properties
  52          in this object */
  53      var $_properties = array();
  54  
  55      /** an assoc with the names of the properties in this object that
  56          have been changed since they were fetched from the database */
  57      var $_changes = array();
  58  
  59      /** flag that decides if data in this object can be changed.
  60          objects that don't have their table's key column in their
  61          property lists will be flagged as read-only. */
  62      var $_readonly = false;
  63  
  64      /** function or method that implements a validator for fields that
  65          are set, this validator function returns true if the field is
  66          valid, false if not */
  67      var $_validator = null;
  68  
  69      // }}}
  70      // {{{ constructor
  71  
  72      /**
  73       * Constructor
  74       *
  75       * @param $table string the name of the database table
  76       *
  77       * @param $keycolumn mixed string with name of key column, or array of
  78       * strings if the table has a primary key of more than one column
  79       *
  80       * @param $dbh object database connection object
  81       *
  82       * @param $validator mixed function or method used to validate
  83       * each new value, called with three parameters: the name of the
  84       * field/column that is changing, a reference to the new value and
  85       * a reference to this object
  86       *
  87       */
  88      function DB_storage($table, $keycolumn, &$dbh, $validator = null)
  89      {
  90          $this->PEAR('DB_Error');
  91          $this->_table = $table;
  92          $this->_keycolumn = $keycolumn;
  93          $this->_dbh = $dbh;
  94          $this->_readonly = false;
  95          $this->_validator = $validator;
  96      }
  97  
  98      // }}}
  99      // {{{ _makeWhere()
 100  
 101      /**
 102       * Utility method to build a "WHERE" clause to locate ourselves in
 103       * the table.
 104       *
 105       * XXX future improvement: use rowids?
 106       *
 107       * @access private
 108       */
 109      function _makeWhere($keyval = null)
 110      {
 111          if (is_array($this->_keycolumn)) {
 112              if ($keyval === null) {
 113                  for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
 114                      $keyval[] = $this->{$this->_keycolumn[$i]};
 115                  }
 116              }
 117              $whereclause = '';
 118              for ($i = 0; $i < sizeof($this->_keycolumn); $i++) {
 119                  if ($i > 0) {
 120                      $whereclause .= ' AND ';
 121                  }
 122                  $whereclause .= $this->_keycolumn[$i];
 123                  if (is_null($keyval[$i])) {
 124                      // there's not much point in having a NULL key,
 125                      // but we support it anyway
 126                      $whereclause .= ' IS NULL';
 127                  } else {
 128                      $whereclause .= ' = ' . $this->_dbh->quote($keyval[$i]);
 129                  }
 130              }
 131          } else {
 132              if ($keyval === null) {
 133                  $keyval = @$this->{$this->_keycolumn};
 134              }
 135              $whereclause = $this->_keycolumn;
 136              if (is_null($keyval)) {
 137                  // there's not much point in having a NULL key,
 138                  // but we support it anyway
 139                  $whereclause .= ' IS NULL';
 140              } else {
 141                  $whereclause .= ' = ' . $this->_dbh->quote($keyval);
 142              }
 143          }
 144          return $whereclause;
 145      }
 146  
 147      // }}}
 148      // {{{ setup()
 149  
 150      /**
 151       * Method used to initialize a DB_storage object from the
 152       * configured table.
 153       *
 154       * @param $keyval mixed the key[s] of the row to fetch (string or array)
 155       *
 156       * @return int DB_OK on success, a DB error if not
 157       */
 158      function setup($keyval)
 159      {
 160          $whereclause = $this->_makeWhere($keyval);
 161          $query = 'SELECT * FROM ' . $this->_table . ' WHERE ' . $whereclause;
 162          $sth = $this->_dbh->query($query);
 163          if (DB::isError($sth)) {
 164              return $sth;
 165          }
 166          $row = $sth->fetchRow(DB_FETCHMODE_ASSOC);
 167          if (DB::isError($row)) {
 168              return $row;
 169          }
 170          if (!$row) {
 171              return $this->raiseError(null, DB_ERROR_NOT_FOUND, null, null,
 172                                       $query, null, true);
 173          }
 174          foreach ($row as $key => $value) {
 175              $this->_properties[$key] = true;
 176              $this->$key = $value;
 177          }
 178          return DB_OK;
 179      }
 180  
 181      // }}}
 182      // {{{ insert()
 183  
 184      /**
 185       * Create a new (empty) row in the configured table for this
 186       * object.
 187       */
 188      function insert($newpk)
 189      {
 190          if (is_array($this->_keycolumn)) {
 191              $primarykey = $this->_keycolumn;
 192          } else {
 193              $primarykey = array($this->_keycolumn);
 194          }
 195          settype($newpk, "array");
 196          for ($i = 0; $i < sizeof($primarykey); $i++) {
 197              $pkvals[] = $this->_dbh->quote($newpk[$i]);
 198          }
 199  
 200          $sth = $this->_dbh->query("INSERT INTO $this->_table (" .
 201                                    implode(",", $primarykey) . ") VALUES(" .
 202                                    implode(",", $pkvals) . ")");
 203          if (DB::isError($sth)) {
 204              return $sth;
 205          }
 206          if (sizeof($newpk) == 1) {
 207              $newpk = $newpk[0];
 208          }
 209          $this->setup($newpk);
 210      }
 211  
 212      // }}}
 213      // {{{ toString()
 214  
 215      /**
 216       * Output a simple description of this DB_storage object.
 217       * @return string object description
 218       */
 219      function toString()
 220      {
 221          $info = strtolower(get_class($this));
 222          $info .= " (table=";
 223          $info .= $this->_table;
 224          $info .= ", keycolumn=";
 225          if (is_array($this->_keycolumn)) {
 226              $info .= "(" . implode(",", $this->_keycolumn) . ")";
 227          } else {
 228              $info .= $this->_keycolumn;
 229          }
 230          $info .= ", dbh=";
 231          if (is_object($this->_dbh)) {
 232              $info .= $this->_dbh->toString();
 233          } else {
 234              $info .= "null";
 235          }
 236          $info .= ")";
 237          if (sizeof($this->_properties)) {
 238              $info .= " [loaded, key=";
 239              $keyname = $this->_keycolumn;
 240              if (is_array($keyname)) {
 241                  $info .= "(";
 242                  for ($i = 0; $i < sizeof($keyname); $i++) {
 243                      if ($i > 0) {
 244                          $info .= ",";
 245                      }
 246                      $info .= $this->$keyname[$i];
 247                  }
 248                  $info .= ")";
 249              } else {
 250                  $info .= $this->$keyname;
 251              }
 252              $info .= "]";
 253          }
 254          if (sizeof($this->_changes)) {
 255              $info .= " [modified]";
 256          }
 257          return $info;
 258      }
 259  
 260      // }}}
 261      // {{{ dump()
 262  
 263      /**
 264       * Dump the contents of this object to "standard output".
 265       */
 266      function dump()
 267      {
 268          foreach ($this->_properties as $prop => $foo) {
 269              print "$prop = ";
 270              print htmlentities($this->$prop);
 271              print "<br />\n";
 272          }
 273      }
 274  
 275      // }}}
 276      // {{{ &create()
 277  
 278      /**
 279       * Static method used to create new DB storage objects.
 280       * @param $data assoc. array where the keys are the names
 281       *              of properties/columns
 282       * @return object a new instance of DB_storage or a subclass of it
 283       */
 284      function &create($table, &$data)
 285      {
 286          $classname = strtolower(get_class($this));
 287          $obj =& new $classname($table);
 288          foreach ($data as $name => $value) {
 289              $obj->_properties[$name] = true;
 290              $obj->$name = &$value;
 291          }
 292          return $obj;
 293      }
 294  
 295      // }}}
 296      // {{{ loadFromQuery()
 297  
 298      /**
 299       * Loads data into this object from the given query.  If this
 300       * object already contains table data, changes will be saved and
 301       * the object re-initialized first.
 302       *
 303       * @param $query SQL query
 304       *
 305       * @param $params parameter list in case you want to use
 306       * prepare/execute mode
 307       *
 308       * @return int DB_OK on success, DB_WARNING_READ_ONLY if the
 309       * returned object is read-only (because the object's specified
 310       * key column was not found among the columns returned by $query),
 311       * or another DB error code in case of errors.
 312       */
 313  // XXX commented out for now
 314  /*
 315      function loadFromQuery($query, $params = null)
 316      {
 317          if (sizeof($this->_properties)) {
 318              if (sizeof($this->_changes)) {
 319                  $this->store();
 320                  $this->_changes = array();
 321              }
 322              $this->_properties = array();
 323          }
 324          $rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params);
 325          if (DB::isError($rowdata)) {
 326              return $rowdata;
 327          }
 328          reset($rowdata);
 329          $found_keycolumn = false;
 330          while (list($key, $value) = each($rowdata)) {
 331              if ($key == $this->_keycolumn) {
 332                  $found_keycolumn = true;
 333              }
 334              $this->_properties[$key] = true;
 335              $this->$key = &$value;
 336              unset($value); // have to unset, or all properties will
 337                             // refer to the same value
 338          }
 339          if (!$found_keycolumn) {
 340              $this->_readonly = true;
 341              return DB_WARNING_READ_ONLY;
 342          }
 343          return DB_OK;
 344      }
 345   */
 346  
 347      // }}}
 348      // {{{ set()
 349  
 350      /**
 351       * Modify an attriute value.
 352       */
 353      function set($property, $newvalue)
 354      {
 355          // only change if $property is known and object is not
 356          // read-only
 357          if ($this->_readonly) {
 358              return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
 359                                       null, null, null, true);
 360          }
 361          if (@isset($this->_properties[$property])) {
 362              if (empty($this->_validator)) {
 363                  $valid = true;
 364              } else {
 365                  $valid = @call_user_func($this->_validator,
 366                                           $this->_table,
 367                                           $property,
 368                                           $newvalue,
 369                                           $this->$property,
 370                                           $this);
 371              }
 372              if ($valid) {
 373                  $this->$property = $newvalue;
 374                  if (empty($this->_changes[$property])) {
 375                      $this->_changes[$property] = 0;
 376                  } else {
 377                      $this->_changes[$property]++;
 378                  }
 379              } else {
 380                  return $this->raiseError(null, DB_ERROR_INVALID, null,
 381                                           null, "invalid field: $property",
 382                                           null, true);
 383              }
 384              return true;
 385          }
 386          return $this->raiseError(null, DB_ERROR_NOSUCHFIELD, null,
 387                                   null, "unknown field: $property",
 388                                   null, true);
 389      }
 390  
 391      // }}}
 392      // {{{ &get()
 393  
 394      /**
 395       * Fetch an attribute value.
 396       *
 397       * @param string attribute name
 398       *
 399       * @return attribute contents, or null if the attribute name is
 400       * unknown
 401       */
 402      function &get($property)
 403      {
 404          // only return if $property is known
 405          if (isset($this->_properties[$property])) {
 406              return $this->$property;
 407          }
 408          $tmp = null;
 409          return $tmp;
 410      }
 411  
 412      // }}}
 413      // {{{ _DB_storage()
 414  
 415      /**
 416       * Destructor, calls DB_storage::store() if there are changes
 417       * that are to be kept.
 418       */
 419      function _DB_storage()
 420      {
 421          if (sizeof($this->_changes)) {
 422              $this->store();
 423          }
 424          $this->_properties = array();
 425          $this->_changes = array();
 426          $this->_table = null;
 427      }
 428  
 429      // }}}
 430      // {{{ store()
 431  
 432      /**
 433       * Stores changes to this object in the database.
 434       *
 435       * @return DB_OK or a DB error
 436       */
 437      function store()
 438      {
 439          foreach ($this->_changes as $name => $foo) {
 440              $params[] = &$this->$name;
 441              $vars[] = $name . ' = ?';
 442          }
 443          if ($vars) {
 444              $query = 'UPDATE ' . $this->_table . ' SET ' .
 445                  implode(', ', $vars) . ' WHERE ' .
 446                  $this->_makeWhere();
 447              $stmt = $this->_dbh->prepare($query);
 448              $res = $this->_dbh->execute($stmt, $params);
 449              if (DB::isError($res)) {
 450                  return $res;
 451              }
 452              $this->_changes = array();
 453          }
 454          return DB_OK;
 455      }
 456  
 457      // }}}
 458      // {{{ remove()
 459  
 460      /**
 461       * Remove the row represented by this object from the database.
 462       *
 463       * @return mixed DB_OK or a DB error
 464       */
 465      function remove()
 466      {
 467          if ($this->_readonly) {
 468              return $this->raiseError(null, DB_WARNING_READ_ONLY, null,
 469                                       null, null, null, true);
 470          }
 471          $query = 'DELETE FROM ' . $this->_table .' WHERE '.
 472              $this->_makeWhere();
 473          $res = $this->_dbh->query($query);
 474          if (DB::isError($res)) {
 475              return $res;
 476          }
 477          foreach ($this->_properties as $prop => $foo) {
 478              unset($this->$prop);
 479          }
 480          $this->_properties = array();
 481          $this->_changes = array();
 482          return DB_OK;
 483      }
 484  
 485      // }}}
 486  }
 487  
 488  /*
 489   * Local variables:
 490   * tab-width: 4
 491   * c-basic-offset: 4
 492   * End:
 493   */
 494  
 495  ?>


Généré le : Sat Feb 24 14:40:03 2007 par Balluche grâce à PHPXref 0.7