[ Index ]
 

Code source de PHP PEAR 1.4.5

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

title

Body

[fermer]

/DB/ -> storage.php (source)

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


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7