home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 August / PCWorld_2001-08_cd.bin / Komunikace / phptriad / phptriadsetup2-11.exe / php / pear / DB / storage.php < prev    next >
PHP Script  |  2001-02-19  |  8KB  |  276 lines

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4.0                                                      |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2001 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. // | Authors: Stig Bakken <ssb@fast.no>                                   |
  17. // |                                                                      |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // DB_storage: a class that lets you return SQL data as objects that
  21. // can be manipulated and that updates the database accordingly.
  22. //
  23.  
  24. require_once "PEAR.php";
  25. require_once "DB.php";
  26.  
  27. function DB_storage_destructor() {
  28.     global $DB_storage_object_list;
  29.  
  30.     if (is_array($DB_storage_object_list)) {
  31.     reset($DB_storage_object_list);
  32.     while (list($ind, $obj) = each($DB_storage_object_list)) {
  33.         $obj->destroy();
  34.     }
  35.     $DB_storage_object_list = null;
  36.     }
  37. }
  38.  
  39. class DB_storage extends PEAR
  40. {
  41.     /** the name of the table (or view, if the backend database supports
  42.         updates in views) we hold data from */
  43.     var $_table = null;
  44.     /** which column in the table contains primary keys */
  45.     var $_keycolumn = null;
  46.     /** DB connection handle used for all transactions */
  47.     var $_dbh = null;
  48.     /** an assoc with the names of database fields stored as properties
  49.     in this object */
  50.     var $_properties = array();
  51.     /** an assoc with the names of the properties in this object that
  52.     have been changed since they were fetched from the database */
  53.     var $_changes = array();
  54.     /** flag that decides if data in this object can be changed.
  55.     objects that don't have their table's key column in their
  56.     property lists will be flagged as read-only. */
  57.     var $_readonly = false;
  58.  
  59.     /**
  60.      * Constructor, adds itself to the DB_storage class's list of
  61.      * objects that should have their "destroy" method called when
  62.      * PHP shuts down (poor man's destructors).
  63.      */
  64.     function DB_storage($table, $keycolumn, &$dbh) {
  65.     global $DB_storage_object_list;
  66.     if (is_array($DB_storage_object_list)) {
  67.         $DB_storage_object_list[] = &$this;
  68.     } else {
  69.         $DB_storage_object_list = array(&$this);
  70.     }
  71.     $this->_table = $table;
  72.     $this->_keycolumn = $keycolumn;
  73.     $this->_dbh = $dbh;
  74.     $this->_readonly = false;
  75.     }
  76.  
  77.     /**
  78.      * Method used to initialize a DB_storage object from the
  79.      * configured table.
  80.      * @param $keyval the key of the row to fetch
  81.      * @return int DB_OK on success, DB error if not
  82.      */
  83.     function setup($keyval) {
  84.     if (is_int($keyval)) {
  85.         $qval = "$keyval";
  86.     } else {
  87.         $qval = "'" . $this->_dbh->quoteString($keyval) . "'";
  88.     }
  89.     $sth = $this->_dbh->query("SELECT * FROM " .
  90.                   $this->_table . " WHERE " .
  91.                   $this->_keycolumn . " = $qval");
  92.     if (DB::isError($sth)) {
  93.         return $sth;
  94.     }
  95.     while ($row = $sth->fetchRow(DB_FETCHMODE_ASSOC)) {
  96.         reset($row);
  97.         while (list($key, $value) = each($row)) {
  98.         $this->_properties[$key] = true;
  99.         $this->$key = &$value;
  100.         unset($value);
  101.         }
  102.     }
  103.     }
  104.  
  105.     /**
  106.      * Create a new (empty) row in the configured table for this
  107.      * object.
  108.      */
  109.     function insert($newid = false) {
  110.     if (is_int($newid)) {
  111.         $qid = "$newid";
  112.     } else {
  113.         $qid = "'" . $this->_dbh->quoteString($newid) . "'";
  114.     }
  115.     $sth = $this->_dbh->query("INSERT INTO " .
  116.                   $this->_table . " (" .
  117.                   $this->_keycolumn .
  118.                   ") VALUES($qid)");
  119.     if (DB::isError($sth)) {
  120.         return $sth;
  121.     }
  122.     $this->setup($newid);
  123.     }
  124.  
  125.     /**
  126.      * Output a simple description of this DB_storage object.
  127.      * @return string object description
  128.      */
  129.     function toString() {
  130.     $info = get_class(&$this);
  131.     $info .= " (table=";
  132.     $info .= $this->_table;
  133.     $info .= ", keycolumn=";
  134.     $info .= $this->_keycolumn;
  135.     $info .= ", dbh=";
  136.     if (is_object($this->_dbh)) {
  137.         $info .= $this->_dbh->toString();
  138.     } else {
  139.         $info .= "null";
  140.     }
  141.     $info .= ")";
  142.     if (sizeof($this->_properties)) {
  143.         $keyname = $this->_keycolumn;
  144.         $key = $this->$keyname;
  145.         $info .= " [loaded, key=$key]";
  146.     }
  147.     if (sizeof($this->_changes)) {
  148.         $info .= " [modified]";
  149.     }
  150.     return $info;
  151.     }
  152.  
  153.     /**
  154.      * Dump the contents of this object to "standard output".
  155.      */
  156.     function dump() {
  157.     reset($this->_properties);
  158.     while (list($prop, $foo) = each($this->_properties)) {
  159.         print "$prop = ";
  160.         print htmlentities($this->$prop);
  161.         print "<BR>\n";
  162.     }
  163.     }
  164.  
  165.     /**
  166.      * Static method used to create new DB storage objects.
  167.      * @param $data assoc. array where the keys are the names
  168.      *              of properties/columns
  169.      * @return object a new instance of DB_storage or a subclass of it
  170.      */
  171.     function &create($table, &$data) {
  172.     $classname = get_class(&$this);
  173.     $obj = new $classname($table);
  174.     reset($data);
  175.     while (list($name, $value) = each($data)) {
  176.         $obj->_properties[$name] = true;
  177.         $obj->$name = &$value;
  178.     }
  179.     return $obj;
  180.     }
  181.  
  182.     /**
  183.      * Loads data into this object from the given query.  If this
  184.      * object already contains table data, changes will be saved and
  185.      * the object re-initialized first.
  186.      *
  187.      * @param $query SQL query
  188.      *
  189.      * @param $params parameter list in case you want to use
  190.      * prepare/execute mode
  191.      *
  192.      * @return int DB_OK on success, DB_WARNING_READ_ONLY if the
  193.      * returned object is read-only (because the object's specified
  194.      * key column was not found among the columns returned by $query),
  195.      * or another DB error code in case of errors.
  196.      */
  197.     function loadFromQuery($query, $params = false) {
  198.     if (sizeof($this->_properties)) {
  199.         if (sizeof($this->_changes)) {
  200.         $this->store();
  201.         $this->_changes = array();
  202.         }
  203.         $this->_properties = array();
  204.     }
  205.     $rowdata = $this->_dbh->getRow($query, DB_FETCHMODE_ASSOC, $params);
  206.     if (DB::isError($rowdata)) {
  207.         return $rowdata;
  208.     }
  209.     reset($rowdata);
  210.     $found_keycolumn = false;
  211.     while (list($key, $value) = each($rowdata)) {
  212.         if ($key == $this->_keycolumn) {
  213.         $found_keycolumn = true;
  214.         }
  215.         $this->_properties[$key] = true;
  216.         $this->$key = &$value;
  217.         unset($value); // have to unset, or all properties will
  218.                    // refer to the same value
  219.     }
  220.     if (!$found_keycolumn) {
  221.         $this->_readonly = true;
  222.         return DB_WARNING_READ_ONLY;
  223.     }
  224.     return DB_OK;
  225.     }
  226.  
  227.     function set($property, &$newvalue) {
  228.     // only change if $property is known and object is not
  229.     // read-only
  230.     if (!$this->_readonly && isset($this->_properties[$property])) {
  231.         $this->$property = $newvalue;
  232.         $this->_changes[$property]++;
  233.         return true;
  234.     }
  235.     return false;
  236.     }
  237.  
  238.     function &get($property) {
  239.     // only return if $property is known
  240.     if (isset($this->_properties[$property])) {
  241.         return $this->$property;
  242.     }
  243.     return null;
  244.     }
  245.  
  246.     function destroy($discard = false) {
  247.     if (!$discard && sizeof($this->_changes)) {
  248.         $this->store();
  249.     }
  250.     $this->_properties = array();
  251.     $this->_changes = array();
  252.     $this->_table = null;
  253.     }
  254.  
  255.     function store() {
  256.     while (list($name, $changed) = each($this->_changes)) {
  257.         $params[] = &$this->$name;
  258.         $vars[] = $name . ' = ?';
  259.     }
  260.     if ($vars) {
  261.         $query = 'UPDATE ' . $this->_table . ' SET ' .
  262.         implode(', ', $vars) . ' WHERE id = ?';
  263.         $params[] = $this->id;
  264.         $stmt = $this->_dbh->prepare($query);
  265.         $res = $this->_dbh->execute($stmt, &$params);
  266.         if (DB::isError($res)) {
  267.         return $res;
  268.         }
  269.         $this->_changes = array();
  270.     }
  271.     return DB_OK;
  272.     }
  273. }
  274.  
  275. ?>
  276.