OCI8PreparedStatement.php

Go to the documentation of this file.
00001 <?php 00002 /* 00003 * $Id: OCI8PreparedStatement.php,v 1.13 2004/03/20 04:16:50 hlellelid 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 require_once 'creole/PreparedStatement.php'; 00023 require_once 'creole/common/PreparedStatementCommon.php'; 00024 00033 class OCI8PreparedStatement extends PreparedStatementCommon implements PreparedStatement { 00034 00042 private $lobDescriptors = array(); 00043 00049 private $lobs = array(); 00050 00055 function close() 00056 { 00057 @OCIFreeStatement($this->stmt); 00058 } 00059 00065 protected function escape($str) 00066 { 00067 return str_replace("'","''", $str); 00068 } 00069 00077 public function executeQuery($p1 = null, $fetchmode = null) 00078 { 00079 $params = null; 00080 if ($fetchmode !== null) { 00081 $params = $p1; 00082 } elseif ($p1 !== null) { 00083 if (is_array($p1)) $params = $p1; 00084 else $fetchmode = $p1; 00085 } 00086 00087 if ($params) { 00088 for($i=0,$cnt=count($params); $i < $cnt; $i++) { 00089 $this->set($i+1, $params[$i]); 00090 } 00091 } 00092 00093 $this->updateCount = null; // reset 00094 00095 $sql = $this->sqlToOracleBindVars($sql); 00096 00097 if ($this->limit > 0) { 00098 $this->conn->applyLimit($sql, $this->offset, $this->limit); 00099 } elseif ($offset > 0) { 00100 throw new SQLException('Cannot specify an offset without limit.'); 00101 } 00102 00103 $result = OCIParse($this->conn->getResource(), $sql); 00104 if (!$result) { 00105 throw new SQLException("Unable to prepare query", $this->conn->nativeError(), $this->sqlToOracleBindVars($sql)); 00106 } 00107 00108 // bind all variables 00109 $this->bindVars($result); 00110 00111 $success = OCIExecute($result, OCI_DEFAULT); 00112 if (!$success) { 00113 throw new SQLException("Unable to execute query", $this->conn->nativeError($result), $this->sqlToOracleBindVars($sql)); 00114 } 00115 00116 $this->resultSet = new OCI8ResultSet($this->conn, $result, $fetchmode); 00117 00118 return $this->resultSet; 00119 } 00120 00128 public function executeUpdate($params = null) 00129 { 00130 if ($params) { 00131 for($i=0,$cnt=count($params); $i < $cnt; $i++) { 00132 $this->set($i+1, $params[$i]); 00133 } 00134 } 00135 00136 if($this->resultSet) $this->resultSet->close(); 00137 $this->resultSet = null; // reset 00138 00139 $stmt = OCIParse($this->conn->getResource(), $this->sqlToOracleBindVars($this->sql)); 00140 if (!$stmt) { 00141 throw new SQLException("Unable to prepare update", $this->conn->nativeError(), $this->sqlToOracleBindVars($sql)); 00142 } 00143 00144 // bind all variables 00145 $this->bindVars($stmt); 00146 00147 // Even if autocommit is on, delay commit until after LOBS have been saved 00148 $success = OCIExecute($stmt, OCI_DEFAULT); 00149 if (!$success) { 00150 throw new SQLException("Unable to execute update", $this->conn->nativeError($stmt), $this->sqlToOracleBindVars($sql)); 00151 } 00152 00153 // save data in any LOB descriptors, then free them 00154 foreach($this->lobDescriptors as $paramIndex => $lobster) { 00155 $lob = $this->lobs[$paramIndex]; // corresponding Blob/Clob 00156 if ($lob->isFromFile()) { 00157 $success = $lobster->savefile($lob->getInputFile()); 00158 } else { 00159 $success = $lobster->save($lob->getContents()); 00160 } 00161 if (!$success) { 00162 $lobster->free(); 00163 throw new SQLException("Error saving lob bound to " . $paramIndex); 00164 } 00165 $lobster->free(); 00166 } 00167 00168 if ($this->conn->getAutoCommit()) { 00169 OCICommit($this->conn->getResource()); // perform deferred commit 00170 } 00171 00172 $this->updateCount = @OCIRowCount($stmt); 00173 00174 return $this->updateCount; 00175 } 00176 00190 private function bindVars($stmt) 00191 { 00192 foreach ($this->boundInVars as $idx => $val) { 00193 $idxName = ":var" . $idx; 00194 if (is_a($val, 'Blob') && !OCIBindByName($stmt, $idxName, $this->lobDescriptors[$idx], -1, OCI_B_BLOB)) { 00195 throw new SQLException("Erorr binding blob to placeholder " . $idx); 00196 } elseif (is_a($val, 'Clob') && !OCIBindByName($stmt, $idxName, $this->lobDescriptors[$idx], -1, OCI_B_CLOB)) { 00197 throw new SQLException("Erorr binding clob to placeholder " . $idx); 00198 } elseif (!OCIBindByName($stmt, $idxName, $val, -1)) { 00199 throw new SQLException("Erorr binding value to placeholder " . $idx); 00200 } 00201 } // foreach 00202 } 00203 00204 00215 private function sqlToOracleBindVars($sql) 00216 { 00217 $out = ""; 00218 $in_literal = 0; 00219 $idxNum = 1; 00220 for ($i = 0; $i < strlen($sql); $i++) { 00221 $char = $sql[$i]; 00222 if (strcmp($char,"'")==0) { 00223 $in_literal = ~$in_literal; 00224 } 00225 if (strcmp($char,"?")==0 && !$in_literal) { 00226 $out .= ":var" . $idxNum++; 00227 } else { 00228 $out .= $char; 00229 } 00230 } 00231 return $out; 00232 } 00233 00239 function setBlob($paramIndex, $blob) 00240 { 00241 require_once 'creole/util/Blob.php'; 00242 if (!($blob instanceof Blob)) { 00243 $b = new Blob(); 00244 $b->setContents($blob); 00245 $blob = $b; 00246 } 00247 $this->lobDescriptors[$paramIndex] = OCINewDescriptor($this->conn->getResource(), OCI_D_LOB); 00248 $this->lobs[$paramIndex] = $blob; 00249 } 00250 00256 function setClob($paramIndex, $clob) 00257 { 00258 require_once 'creole/util/Clob.php'; 00259 if (!($clob instanceof Clob)) { 00260 $c = new Clob(); 00261 $c->setContents($clob); 00262 $clob = $c; 00263 } 00264 $this->lobDescriptors[$paramIndex] = OCINewDescriptor($this->conn->getResource(), OCI_D_LOB); 00265 $this->lobs[$paramIndex] = $clob; 00266 } 00267 00268 }

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


Copyright © 2004 Hans Lellelid  
Creole[php5] CVS