cvs: /php4/pear DB.php /php4/pear/DB common.php mysql.php pgsql.php storage.php
| From: | Stig Bakken | 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;
}
}