PreparedStatementCommon.php

Go to the documentation of this file.
00001 <?php 00002 /* 00003 * $Id: PreparedStatementCommon.php,v 1.2 2004/03/29 18:46:46 micha Exp $ 00004 * 00005 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00006 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00007 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00008 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00009 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00010 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00011 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00012 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00013 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00014 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00015 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00016 * 00017 * This software consists of voluntary contributions made by many individuals 00018 * and is licensed under the LGPL. For more information please see 00019 * <http://creole.phpdb.org>. 00020 */ 00021 00022 // 00023 // STATUS: 00024 // - ported: y 00025 // - exceptions: y 00026 // - compiled: y 00027 // - tested: n 00028 // 00029 00030 require_once 'creole/PreparedStatement.php'; 00031 00044 class PreparedStatementCommon extends PreparedStatement 00045 { 00050 var $conn; 00051 00056 var $limit = 0; 00057 00063 var $offset = 0; 00064 00069 var $sql; 00070 00075 var $positions; 00076 00077 00082 var $positionsCount; 00083 00088 var $boundInVars = array(); 00089 00094 var $resultSet; 00095 00100 var $updateCount; 00101 00110 function PreparedStatementCommon(/*Connection*/ &$conn, &$sql) 00111 { 00112 if (! is_a($conn, 'Connection')) { 00113 trigger_error ( 00114 "PreparedStatementCommon::PreparedStatementCommon(): parameter 1 not of type 'Connection' !", 00115 E_USER_ERROR 00116 ); 00117 } 00118 00119 $this->conn =& $conn; 00120 $this->sql =& $sql; 00121 00122 // get the positiosn for the '?' in the SQL 00123 // we can move this into its own method if it gets more complex 00124 $positions = array(); 00125 $positionsCount = 0; 00126 $position = 0; 00127 00128 while ($position < strlen($sql) && ($question = strpos($sql, '?', $position)) !== false ) 00129 { 00130 $positions[] = $question; 00131 $position = $question + 1; 00132 $positionsCount++; 00133 } 00134 00135 $this->positions = $positions; 00136 $this->positionsCount = $positionsCount; // save processing later in cases where we may repeatedly exec statement 00137 } 00138 00142 function setLimit($v) 00143 { 00144 $this->limit = (int) $v; 00145 } 00146 00150 function getLimit() 00151 { 00152 return $this->limit; 00153 } 00154 00158 function setOffset($v) 00159 { 00160 $this->offset = (int) $v; 00161 } 00162 00166 function getOffset() 00167 { 00168 return $this->offset; 00169 } 00170 00174 function & getResultSet() 00175 { 00176 return $this->resultSet; 00177 } 00178 00182 function getUpdateCount() 00183 { 00184 return $this->updateCount; 00185 } 00186 00191 function getMoreResults() 00192 { 00193 if ($this->resultSet) $this->resultSet->close(); 00194 $this->resultSet = null; 00195 return false; 00196 } 00197 00201 function & getConnection() 00202 { 00203 return $this->conn; 00204 } 00205 00211 function getResource() 00212 { 00213 return null; 00214 } 00215 00219 function close() 00220 { 00221 } 00222 00230 function replaceParams() 00231 { 00232 // Default behavior for this function is to behave in 'emulated' mode. 00233 $sql = ''; 00234 $last_position = 0; 00235 00236 for ($position = 0; $position < $this->positionsCount; $position++) { 00237 if (!isset($this->boundInVars[$position + 1])) { 00238 return new SQLException(CREOLE_ERROR, 'Replace params: undefined query param: ' . ($position + 1)); 00239 } 00240 $current_position = $this->positions[$position]; 00241 $sql .= substr($this->sql, $last_position, $current_position - $last_position); 00242 $sql .= $this->boundInVars[$position + 1]; 00243 $last_position = $current_position + 1; 00244 } 00245 // append the rest of the query 00246 $sql .= substr($this->sql, $last_position); 00247 00248 return $sql; 00249 } 00250 00260 function & executeQuery($p1 = null, $fetchmode = null) 00261 { 00262 $params = null; 00263 if ($fetchmode !== null) { 00264 $params = $p1; 00265 } elseif ($p1 !== null) { 00266 if (is_array($p1)) $params = $p1; 00267 else $fetchmode = $p1; 00268 } 00269 00270 if ($params) { 00271 for($i=0,$cnt=count($params); $i < $cnt; $i++) { 00272 $this->set($i+1, $params[$i]); 00273 } 00274 } 00275 00276 $this->updateCount = null; // reset 00277 $sql = $this->replaceParams(); 00278 00279 if (Creole::isError($sql)) { 00280 return $sql; 00281 } 00282 00283 if ($this->limit > 0) { 00284 $this->conn->applyLimit($sql, $this->offset, $this->limit); 00285 } elseif ($this->offset > 0) { 00286 return new SQLException(CREOLE_ERROR, 'Cannot specify an offset without limit.'); 00287 } 00288 00289 $this->resultSet =& $this->conn->executeQuery($sql, $fetchmode); 00290 return $this->resultSet; 00291 } 00292 00300 function & executeUpdate($params = null) 00301 { 00302 if ($params) { 00303 for($i=0,$cnt=count($params); $i < $cnt; $i++) { 00304 $this->set($i+1, $params[$i]); 00305 } 00306 } 00307 00308 if($this->resultSet) $this->resultSet->close(); 00309 $this->resultSet = null; // reset 00310 $sql = $this->replaceParams(); 00311 00312 if (Creole::isError($sql)) { 00313 return $sql; 00314 } 00315 00316 $this->updateCount =& $this->conn->executeUpdate($sql); 00317 return $this->updateCount; 00318 } 00319 00325 function escape(&$str) 00326 { 00327 trigger_error ( 00328 "PreparedStatementCommon::escape(): abstract function has to be reimplemented !", 00329 E_USER_ERROR 00330 ); 00331 } 00332 00344 function set($paramIndex, $value) 00345 { 00346 $type = gettype($value); 00347 if ($type == "object") { 00348 if (is_a($value, 'Blob')) { 00349 $this->setBlob($paramIndex, $value); 00350 } elseif (is_a($value, 'Clob')) { 00351 $this->setClob($paramIndex, $value); 00352 } elseif (is_a($value, 'Date')) { 00353 // can't be sure if the column type is a DATE, TIME, or TIMESTAMP column 00354 // we'll just use TIMESTAMP by default; hopefully DB won't complain (if 00355 // it does, then this method just shouldn't be used). 00356 $this->setTimestamp($paramIndex, $value); 00357 } else { 00358 return new SQLException(CREOLE_ERROR_UNSUPPORTED, "Unsupported object type passed to set(): " . get_class($value)); 00359 } 00360 } else { 00361 if ($type == "integer") { 00362 $type = "int"; 00363 } elseif ($type == "double") { 00364 $type = "float"; 00365 } 00366 $setter = 'set' . ucfirst($type); // PHP types are case-insensitive, but we'll do this in case that changes 00367 $this->$setter($paramIndex, $value); 00368 } 00369 00370 return true; 00371 } 00372 00381 function setArray($paramIndex, $value) 00382 { 00383 if ($value === null) { 00384 $this->setNull($paramIndex); 00385 } else { 00386 $this->boundInVars[$paramIndex] = "'" . $this->escape(serialize($value)) . "'"; 00387 } 00388 } 00389 00397 function setBoolean($paramIndex, $value) 00398 { 00399 if ($value === null) { 00400 $this->setNull($paramIndex); 00401 } else { 00402 $this->boundInVars[$paramIndex] = (int) $value; 00403 } 00404 } 00405 00406 00410 function setBlob($paramIndex, $blob) 00411 { 00412 if ($blob === null) { 00413 $this->setNull($paramIndex); 00414 } else { 00415 $this->boundInVars[$paramIndex] = "'" . $this->escape((string) $blob) . "'"; 00416 } 00417 } 00418 00422 function setClob($paramIndex, $clob) 00423 { 00424 if ($clob === null) { 00425 $this->setNull($paramIndex); 00426 } else { 00427 $this->boundInVars[$paramIndex] = "'" . $this->escape((string) $clob) . "'"; 00428 } 00429 } 00430 00436 function setDate($paramIndex, $value) 00437 { 00438 if (is_numeric($value)) $value = date("Y-m-d", $value); 00439 if (is_object($value)) $value = date("Y-m-d", $value->getTime()); 00440 if ($value === null) { 00441 $this->setNull($paramIndex); 00442 } else { 00443 $this->boundInVars[$paramIndex] = "'" . $this->escape($value) . "'"; 00444 } 00445 } 00446 00452 function setDecimal($paramIndex, $value) 00453 { 00454 if ($value === null) { 00455 $this->setNull($paramIndex); 00456 } else { 00457 $this->boundInVars[$paramIndex] = (float) $value; 00458 } 00459 } 00460 00466 function setDouble($paramIndex, $value) 00467 { 00468 if ($value === null) { 00469 $this->setNull($paramIndex); 00470 } else { 00471 $this->boundInVars[$paramIndex] = (double) $value; 00472 } 00473 } 00474 00480 function setFloat($paramIndex, $value) 00481 { 00482 if ($value === null) { 00483 $this->setNull($paramIndex); 00484 } else { 00485 $this->boundInVars[$paramIndex] = (float) $value; 00486 } 00487 } 00488 00494 function setInt($paramIndex, $value) 00495 { 00496 if ($value === null) { 00497 $this->setNull($paramIndex); 00498 } else { 00499 $this->boundInVars[$paramIndex] = (int) $value; 00500 } 00501 } 00502 00508 function setInteger($paramIndex, $value) 00509 { 00510 $this->setInt($paramIndex, $value); 00511 } 00512 00517 function setNull($paramIndex) 00518 { 00519 $this->boundInVars[$paramIndex] = 'NULL'; 00520 } 00521 00527 function setString($paramIndex, $value) 00528 { 00529 if ($value === null) { 00530 $this->setNull($paramIndex); 00531 } else { 00532 $this->boundInVars[$paramIndex] = "'" . $this->escape( (string) $value ) . "'"; 00533 } 00534 } 00535 00541 function setTime($paramIndex, $value) 00542 { 00543 if (is_numeric($value)) $value = date("H:i:s", $value); 00544 elseif (is_object($value)) $value = date("H:i:s", $value->getTime()); 00545 00546 if ($value === null) { 00547 $this->setNull($paramIndex); 00548 } else { 00549 $this->boundInVars[$paramIndex] = "'" . $this->escape($value) . "'"; 00550 } 00551 } 00552 00558 function setTimestamp($paramIndex, $value) 00559 { 00560 if (is_numeric($value)) $value = date('Y-m-d H:i:s', $value); 00561 elseif (is_object($value)) $value = date("Y-m-d H:i:s", $value->getTime()); 00562 00563 if ($value === null) { 00564 $this->setNull($paramIndex); 00565 } else { 00566 $this->boundInVars[$paramIndex] = "'".$value."'"; 00567 } 00568 } 00569 00570 }

This file is part of the Creole[php4] library.


Copyright © 2004 Hans Lellelid  
Creole[php4] CVS