00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00056 private $columns = array();
00057
00062 function close()
00063 {
00064 if (isset($this->stmt))
00065 @oci_free_statement($this->stmt);
00066 }
00067
00073 protected function escape($str)
00074 {
00075 return $str;
00076 }
00077
00085 public function executeQuery($p1 = null, $fetchmode = null)
00086 {
00087 $params = null;
00088 if ($fetchmode !== null) {
00089 $params = $p1;
00090 } elseif ($p1 !== null) {
00091 if (is_array($p1)) $params = $p1;
00092 else $fetchmode = $p1;
00093 }
00094
00095 if ($params) {
00096 for($i=0,$cnt=count($params); $i < $cnt; $i++) {
00097 $this->set($i+1, $params[$i]);
00098 }
00099 }
00100
00101 $this->updateCount = null;
00102
00103 $sql = $this->sqlToOracleBindVars($this->sql);
00104
00105 if ($this->limit > 0 || $this->offset > 0) {
00106 $this->conn->applyLimit($sql, $this->offset, $this->limit);
00107 }
00108
00109 $result = oci_parse($this->conn->getResource(), $sql);
00110 if (!$result) {
00111 throw new SQLException("Unable to prepare query", $this->conn->nativeError(), $this->sqlToOracleBindVars($this->sql));
00112 }
00113
00114
00115 $this->bindVars($result);
00116
00117 $success = oci_execute($result, OCI_DEFAULT);
00118 if (!$success) {
00119 throw new SQLException("Unable to execute query", $this->conn->nativeError($result), $this->sqlToOracleBindVars($this->sql));
00120 }
00121
00122 $this->resultSet = new OCI8ResultSet($this->conn, $result, $fetchmode);
00123
00124 return $this->resultSet;
00125 }
00126
00134 public function executeUpdate($params = null)
00135 {
00136 if ($params) {
00137 for($i=0,$cnt=count($params); $i < $cnt; $i++) {
00138 $this->set($i+1, $params[$i]);
00139 }
00140 }
00141
00142 if($this->resultSet) $this->resultSet->close();
00143 $this->resultSet = null;
00144
00145 $stmt = oci_parse($this->conn->getResource(), $this->sqlToOracleBindVars($this->sql));
00146
00147 if (!$stmt) {
00148 throw new SQLException("Unable to prepare update", $this->conn->nativeError(), $this->sqlToOracleBindVars($this->sql));
00149 }
00150
00151
00152 $this->bindVars($stmt);
00153
00154
00155 $success = oci_execute($stmt, OCI_DEFAULT);
00156 if (!$success) {
00157 throw new SQLException("Unable to execute update", $this->conn->nativeError($stmt), $this->sqlToOracleBindVars($this->sql));
00158 }
00159
00160
00161 foreach($this->lobDescriptors as $paramIndex => $lobster) {
00162 $lob = $this->lobs[$paramIndex];
00163 if ($lob->isFromFile()) {
00164 $success = $lobster->savefile($lob->getInputFile());
00165 } else {
00166 $success = $lobster->save($lob->getContents());
00167 }
00168 if (!$success) {
00169 $lobster->free();
00170 throw new SQLException("Error saving lob bound to " . $paramIndex);
00171 }
00172 $lobster->free();
00173 }
00174
00175 if ($this->conn->getAutoCommit()) {
00176 oci_commit($this->conn->getResource());
00177 }
00178
00179 $this->updateCount = @oci_num_rows($stmt);
00180
00181 return $this->updateCount;
00182 }
00183
00197 private function bindVars($stmt)
00198 {
00199 foreach ($this->boundInVars as $idx => $val) {
00200 $idxName = ":var" . $idx;
00201 if (!oci_bind_by_name($stmt, $idxName, $this->boundInVars[$idx], -1)) {
00202 throw new SQLException("Erorr binding value to placeholder " . $idx);
00203 }
00204 }
00205
00206 foreach ($this->lobs as $idx => $val) {
00207 $idxName = ":var" . $idx;
00208 if (class_exists('Blob') && $val instanceof Blob){
00209 if (!oci_bind_by_name($stmt, $idxName, $this->lobDescriptors[$idx], -1, OCI_B_BLOB))
00210 throw new SQLException("Erorr binding blob to placeholder " . $idx);
00211 } elseif (class_exists('Clob') && $val instanceof Clob){
00212 if (!oci_bind_by_name($stmt, $idxName, $this->lobDescriptors[$idx], -1, OCI_B_CLOB))
00213 throw new SQLException("Erorr binding clob to placeholder " . $idx);
00214 }
00215 }
00216 }
00217
00218
00229 private function sqlToOracleBindVars($sql)
00230 {
00231 $out = "";
00232 $in_literal = 0;
00233 $idxNum = 1;
00234 for ($i = 0; $i < strlen($sql); $i++) {
00235 $char = $sql[$i];
00236 if (strcmp($char,"'")==0) {
00237 $in_literal = ~$in_literal;
00238 }
00239 if (strcmp($char,"?")==0 && !$in_literal) {
00240 if (array_key_exists($idxNum, $this->lobs)){
00241 if (class_exists('Blob') && ($this->lobs[$idxNum] instanceof Blob))
00242 $out .= "empty_blob()";
00243 if (class_exists('Clob') && ($this->lobs[$idxNum] instanceof Clob))
00244 $out .= "empty_clob()";
00245 } else
00246 $out .= ":var" . $idxNum;
00247 $idxNum++;
00248 } else {
00249 $out .= $char;
00250 }
00251 }
00252
00253 if (isset($this->lobs) && !empty($this->lobs)) {
00254 $this->setColumnArray();
00255
00256 $retstmt = " Returning ";
00257 $collist = "";
00258 $bindlist = "";
00259 foreach ($this->lobs as $idx=>$val) {
00260 $idxName = ":var" . $idx;
00261 if ((class_exists('Blob') && $val instanceof Blob) || (class_exists('Clob') && $val instanceof Clob)) {
00262
00263 $collist .= $this->columns[$idx-1] . ",";
00264 $bindlist .= $idxName . ",";
00265 }
00266 }
00267
00268 if (!empty($collist))
00269 $out .= $retstmt . rtrim($collist, ",") . " into " . rtrim($bindlist, ",");
00270 }
00271
00272 return $out;
00273 }
00274
00280 function setBlob($paramIndex, $blob)
00281 {
00282 require_once 'creole/util/Blob.php';
00283 if (!($blob instanceof Blob)) {
00284 $b = new Blob();
00285 $b->setContents($blob);
00286 $blob = $b;
00287 }
00288 $this->lobDescriptors[$paramIndex] = oci_new_descriptor($this->conn->getResource(), OCI_D_LOB);
00289 $this->lobs[$paramIndex] = $blob;
00290 }
00291
00297 function setClob($paramIndex, $clob)
00298 {
00299 require_once 'creole/util/Clob.php';
00300 if (!($clob instanceof Clob)) {
00301 $c = new Clob();
00302 $c->setContents($clob);
00303 $clob = $c;
00304 }
00305 $this->lobDescriptors[$paramIndex] = oci_new_descriptor($this->conn->getResource(), OCI_D_LOB);
00306 $this->lobs[$paramIndex] = $clob;
00307 }
00308
00317 function setString($paramIndex, $value)
00318 {
00319 if ($value === null) {
00320 $this->setNull($paramIndex);
00321 } else {
00322
00323
00324 if ( is_object ( $value ) ) {
00325 $this->boundInVars[$paramIndex] = $value->__toString();
00326 } else {
00327 $this->boundInVars[$paramIndex] = (string)$value;
00328 }
00329 }
00330 }
00331
00341 function setTimestamp($paramIndex, $value)
00342 {
00343 if ($value === null) {
00344 $this->setNull($paramIndex);
00345 } else {
00346 if (is_numeric($value)) $value = date('Y-m-d H:i:s', $value);
00347 elseif (is_object($value)) $value = date('Y-m-d H:i:s', $value->getTime());
00348 $this->boundInVars[$paramIndex] = $value;
00349 }
00350 }
00351
00360 function setDate($paramIndex, $value)
00361 {
00362 if ($value === null) {
00363 $this->setNull($paramIndex);
00364 } else {
00365 if (is_numeric($value)) $value = date("Y-m-d", $value);
00366 elseif (is_object($value)) $value = date("Y-m-d", $value->getTime());
00367 $this->boundInVars[$paramIndex] = $value;
00368 }
00369 }
00370
00384 private function setColumnArray()
00385 {
00386 $this->columns = array();
00387
00388
00389 if(strtoupper(substr($this->sql, 0, 6)) == 'INSERT') {
00390 $firstPos = strpos($this->sql, '(');
00391 $secPos = strpos($this->sql, ')');
00392 $collist = substr($this->sql, $firstPos + 1, $secPos - $firstPos - 1);
00393 $this->columns = explode(',', $collist);
00394 }
00395 if (strtoupper(substr($this->sql, 0, 6)) == 'UPDATE') {
00396
00397
00398
00399
00400 $tmp = $this->sql;
00401 $tmp = str_replace(" =", "=", $this->sql);
00402 $tmp = str_replace("= ", "=", $tmp);
00403 $tmp = str_replace(",", " ", $tmp);
00404 $stage1 = explode("=?",$tmp);
00405
00406 foreach($stage1 as $chunk) {
00407 $stage2 = explode(' ', $chunk);
00408 $this->columns[count($this->columns)] = $stage2[count($stage2) - 1];
00409 }
00410 }
00411 }
00412
00417 function setNull($paramIndex)
00418 {
00419 $this->boundInVars[$paramIndex] = '';
00420 }
00421
00422
00423 }
00424