cvs: /php4/pear DB.php /php4/pear/DB common.php mysql.php pgsql.php storage.php

From: Date: Thu, 17 Feb 2000 20:21:33 +0000
Subject: cvs: /php4/pear DB.php /php4/pear/DB common.php mysql.php pgsql.php storage.php
Groups: php.version4 
Request: Send a blank email to php-version4+get-10405@lists.php.net to get a copy of this message
ssb Thu Feb 17 12:21:33 2000 EDT Modified files: /php4/pear DB.php /php4/pear/DB common.php mysql.php pgsql.php storage.php Log: * prepare/execute emulation moved into DB_common * returning references everywhere in DB_mysql and DB_pgsql * added a todo note to DB_pgsql Index: php4/pear/DB.php diff -u php4/pear/DB.php:1.14 php4/pear/DB.php:1.15 --- php4/pear/DB.php:1.14 Mon Feb 14 07:12:20 2000 +++ php4/pear/DB.php Thu Feb 17 12:21:01 2000 @@ -17,7 +17,7 @@ // | | // +----------------------------------------------------------------------+ // -// $Id: DB.php,v 1.14 2000/02/14 15:12:20 ssb Exp $ +// $Id: DB.php,v 1.15 2000/02/17 20:21:01 ssb Exp $ // // Database independent query interface. // @@ -139,7 +139,7 @@ * well as common utility functions for other DB classes. * * DB_common The base for each DB implementation. Provides default - * | implementations (some would say virtual methods) for + * | implementations (in OO lingo virtual methods) for * | the actual DB implementations as well as a bunch of * | query utility functions. * | Index: php4/pear/DB/common.php diff -u php4/pear/DB/common.php:1.8 php4/pear/DB/common.php:1.9 --- php4/pear/DB/common.php:1.8 Mon Feb 14 07:12:21 2000 +++ php4/pear/DB/common.php Thu Feb 17 12:21:02 2000 @@ -123,6 +123,84 @@ // }}} + // {{{ prepare() + + /** + * Prepares a query for multiple execution with execute(). With + * PostgreSQL, this is emulated. + */ + function prepare($query) { + $tokens = split('[\&\?]', $query); + $token = 0; + $types = array(); + for ($i = 0; $i < strlen($query); $i++) { + switch ($query[$i]) { + case '?': + $types[$token++] = DB_PARAM_SCALAR; + break; + case '&': + $types[$token++] = DB_PARAM_OPAQUE; + break; + } + } + $this->prepare_tokens[] = &$tokens; + end($this->prepare_tokens); + $k = key($this->prepare_tokens); + $this->prepare_types[$k] = $types; + return $k; + } + + // }}} + // {{{ execute_emulate_query() + + /** + * @return a string containing the real query run when emulating + * prepare/execute. A DB error code is returned on failure. + */ + function execute_emulate_query($stmt, $data = false) { + $p = &$this->prepare_tokens; + $stmt = 0; // XXX HORRIBLE HACK + if (!isset($this->prepare_tokens[$stmt]) || + !is_array($this->prepare_tokens[$stmt]) || + !sizeof($this->prepare_tokens[$stmt])) { + return DB_ERROR_INVALID; + } + $qq = &$this->prepare_tokens[$stmt]; + $qp = sizeof($qq) - 1; + if ((!$data && $qp > 0) || + (!is_array($data) && $qp > 1) || + (is_array($data) && $qp > sizeof($data))) { + return DB_ERROR_NEED_MORE_DATA; + } + $realquery = $qq[0]; + for ($i = 0; $i < $qp; $i++) { + if ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { + if (is_array($data)) { + $fp = fopen($data[$i], "r"); + } else { + $fp = fopen($data, "r"); + } + $pdata = ''; + if ($fp) { + while (($buf = fread($fp, 4096)) != false) { + $pdata .= $buf; + } + } + } else { + if (is_array($data)) { + $pdata = &$data[$i]; + } else { + $pdata = &$data; + } + } + $realquery .= "'" . $this->quoteString($pdata) . "'"; + $realquery .= $qq[$i + 1]; + } + return $realquery; + } + + // }}} + // {{{ executeMultiple() /** Index: php4/pear/DB/mysql.php diff -u php4/pear/DB/mysql.php:1.11 php4/pear/DB/mysql.php:1.12 --- php4/pear/DB/mysql.php:1.11 Mon Feb 14 07:12:21 2000 +++ php4/pear/DB/mysql.php Thu Feb 17 12:21:02 2000 @@ -26,9 +26,6 @@ // // XXX ERRORMSG: The error message from the mysql function should // be registered here. -// XXX ADDREF: As soon as Zend/PHP gets support for returning -// references, this return value should be made into -// a reference. // if ($GLOBALS['USED_PACKAGES']['DB/mysql']) return; @@ -141,7 +138,7 @@ * @return object a DB_result object on success, a DB error code * on failure */ - function query($query) { + function &query($query) { $result = mysql_query($query, $this->connection); if (!$result) { return $this->errorCode(mysql_errno($this->connection)); @@ -150,7 +147,7 @@ // should return an error code only. if (preg_match('/(SELECT|SHOW)/i', $query)) { $resultObj = new DB_result($this, $result); - return $resultObj; // XXX ADDREF + return $resultObj; } else { return DB_OK; } @@ -329,44 +326,7 @@ * code is returned on failure. */ function execute($stmt, $data = false) { - $p = &$this->prepare_tokens; - $stmt = 0; // XXX HORRIBLE HACK - if (!isset($this->prepare_tokens[$stmt]) || - !is_array($this->prepare_tokens[$stmt]) || - !sizeof($this->prepare_tokens[$stmt])) { - return DB_ERROR_INVALID; - } - $qq = &$this->prepare_tokens[$stmt]; - $qp = sizeof($qq) - 1; - if ((!$data && $qp > 0) || - (!is_array($data) && $qp > 1) || - (is_array($data) && $qp > sizeof($data))) { - return DB_ERROR_NEED_MORE_DATA; - } - $realquery = $qq[0]; - for ($i = 0; $i < $qp; $i++) { - if ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { - if (is_array($data)) { - $fp = fopen($data[$i], "r"); - } else { - $fp = fopen($data, "r"); - } - $pdata = ''; - if ($fp) { - while (($buf = fread($fp, 4096)) != false) { - $pdata .= $buf; - } - } - } else { - if (is_array($data)) { - $pdata = &$data[$i]; - } else { - $pdata = &$data; - } - } - $realquery .= "'" . $this->quoteString($pdata) . "'"; - $realquery .= $qq[$i + 1]; - } + $realquery = $this->execute_emulate_query($stmt, $data); $result = mysql_query($realquery, $this->connection); if (!$result) { return $this->errorCode(mysql_errno($this->connection)); Index: php4/pear/DB/pgsql.php diff -u php4/pear/DB/pgsql.php:1.1 php4/pear/DB/pgsql.php:1.2 --- php4/pear/DB/pgsql.php:1.1 Mon Feb 14 07:42:23 2000 +++ php4/pear/DB/pgsql.php Thu Feb 17 12:21:02 2000 @@ -20,15 +20,25 @@ // Database independent query interface definition for PHP's PostgreSQL // extension. // +// [SSB] Problems in this code: +// +// 1. $this->row is used as a row counter +// for the fetchRow() implementation. There are two problems with this: +// First of all, $this->row is not reset when the result is freed. Also, +// If the user creates two DB_result objects on the same DB connection, +// it will break completely because both result sets will be using the +// same row counter. Solution: change $this->row into an array indexed +// by resource id. +// +// 2. The pgsql extension currently does not have error codes. This +// should be fixed so DB_pgsql can do portable error codes. +// // // XXX legend: // // XXX ERRORMSG: The error message from the mysql function should // be registered here. -// XXX ADDREF: As soon as Zend/PHP gets support for returning -// references, this return value should be made into -// a reference. // if ($GLOBALS['USED_PACKAGES']['DB/pgsql']) return; @@ -134,7 +144,7 @@ * @return object a DB_result object on success, a DB error code * on failure */ - function query($query) { + function &query($query) { $result = pg_exec($this->connection, $query); if (!$result) { return pg_errormessage($this->connection); @@ -143,7 +153,7 @@ // should return an error code only. if (preg_match('/(SELECT|SHOW)/i', $query)) { $resultObj = new DB_result($this, $result); - return $resultObj; // XXX ADDREF + return $resultObj; } else { return DB_OK; } @@ -188,7 +198,7 @@ * @return int an array on success, a DB error code on failure, NULL * if there is no more data */ - function fetchRow($result, $getmode = DB_GETMODE_DEFAULT) { + function &fetchRow($result, $getmode = DB_GETMODE_DEFAULT) { if ($getmode & DB_GETMODE_ASSOC) { $row = pg_fetch_array($result, $this->row); } else { @@ -202,7 +212,7 @@ return $err; } $this->row++; - return $row; // XXX ADDREF + return $row; } // }}} @@ -342,44 +352,7 @@ * code is returned on failure. */ function execute($stmt, $data = false) { - $p = &$this->prepare_tokens; - $stmt = 0; // XXX HORRIBLE HACK - if (!isset($this->prepare_tokens[$stmt]) || - !is_array($this->prepare_tokens[$stmt]) || - !sizeof($this->prepare_tokens[$stmt])) { - return DB_ERROR_INVALID; - } - $qq = &$this->prepare_tokens[$stmt]; - $qp = sizeof($qq) - 1; - if ((!$data && $qp > 0) || - (!is_array($data) && $qp > 1) || - (is_array($data) && $qp > sizeof($data))) { - return DB_ERROR_NEED_MORE_DATA; - } - $realquery = $qq[0]; - for ($i = 0; $i < $qp; $i++) { - if ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE) { - if (is_array($data)) { - $fp = fopen($data[$i], "r"); - } else { - $fp = fopen($data, "r"); - } - $pdata = ''; - if ($fp) { - while (($buf = fread($fp, 4096)) != false) { - $pdata .= $buf; - } - } - } else { - if (is_array($data)) { - $pdata = &$data[$i]; - } else { - $pdata = &$data; - } - } - $realquery .= "'" . $this->quoteString($pdata) . "'"; - $realquery .= $qq[$i + 1]; - } + $realquery = $this->execute_emulate_query($stmt, $data); $result = pg_exec($this->connection, $realquery); if (!$result) { return pg_errormessage($this->connection); Index: php4/pear/DB/storage.php diff -u php4/pear/DB/storage.php:1.1 php4/pear/DB/storage.php:1.2 --- php4/pear/DB/storage.php:1.1 Mon Feb 14 07:12:21 2000 +++ php4/pear/DB/storage.php Thu Feb 17 12:21:02 2000 @@ -91,15 +91,6 @@ return $obj; } - function destroy($discard = false) { - if (!$discard && is_array($this->_changes) && sizeof($this->_changes)) { - $this->store(); - } - $this->_properties = array(); - $this->_changes = array(); - $this->_table = null; - } - /** * Loads data into this object from the given query. If this * object already contains table data, changes will be saved and @@ -116,7 +107,13 @@ * or another DB error code in case of errors. */ function loadFromQuery($query, $params = false) { - $this->destroy(); + if (sizeof($this->_properties)) { + if (sizeof($this->_changes)) { + $this->store(); + $this->_changes = array(); + } + $this->_properties = array(); + } $rowdata = $this->_dbh->getRow($query, DB_GETMODE_ASSOC, $params); if (DB::isError($rowdata)) { return $rowdata; @@ -142,7 +139,7 @@ function set($property, &$newvalue) { // only change if $property is known and object is not // read-only - if (!$this->_readonly && $this->_properties[$property]) { + if (!$this->_readonly && isset($this->_properties[$property])) { $this->$property = $newvalue; $this->_changes[$property]++; return true; @@ -152,16 +149,22 @@ function &get($property) { // only return if $property is known - if ($this->_properties[$property]) { + if (isset($this->_properties[$property])) { return $this->$property; } return null; } - function store() { - if (!is_array($this->_changes)) { - return DB_OK; + function destroy($discard = false) { + if (!$discard && sizeof($this->_changes)) { + $this->store(); } + $this->_properties = array(); + $this->_changes = array(); + $this->_table = null; + } + + function store() { while (list($name, $changed) = each($this->_changes)) { $params[] = &$this->$name; $vars[] = $name . ' = ?'; @@ -170,14 +173,14 @@ $query = 'UPDATE ' . $this->_table . ' SET ' . implode(', ', $vars) . ' WHERE id = ?'; $params[] = $this->id; - $res = sql($query, &$params); - if ($res) { - $this->changes = array(); - $this->postUpdate(); - } else { - return false; + $stmt = $this->_dbh->prepare($query); + $res = $this->_dbh->execute($stmt, &$params); + if (DB::isError($res)) { + return $res; } + $this->_changes = array(); } + return DB_OK; } }

« previous php.version4 (#10405) next »