[ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 /* 3 * $Id: ODBCConnection.php,v 1.6 2006/01/17 19:44:39 hlellelid Exp $ 4 * 5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 * 17 * This software consists of voluntary contributions made by many individuals 18 * and is licensed under the LGPL. For more information please see 19 * <http://creole.phpdb.org>. 20 */ 21 22 require_once 'creole/Connection.php'; 23 require_once 'creole/common/ConnectionCommon.php'; 24 require_once 'creole/drivers/odbc/adapters/ODBCAdapter.php'; 25 26 /** 27 * ODBC implementation of Connection. 28 * 29 * @author Dave Lawson <dlawson@masterytech.com> 30 * @version $Revision: 1.6 $ 31 * @package creole.drivers.odbc 32 */ 33 class ODBCConnection extends ConnectionCommon implements Connection { 34 35 /** 36 * Implements driver-specific behavior 37 * @var ODBCAdapter 38 */ 39 protected $adapter = null; 40 41 /** 42 * Last ODBC result resource from executeQuery/executeUpdate. Used in getUpdateCount() 43 * @var ODBCResultResource 44 */ 45 protected $odbcresult = null; 46 47 /** 48 * @see Connection::connect() 49 */ 50 public function connect($dsninfo, $flags = 0) 51 { 52 if (!function_exists('odbc_connect')) 53 throw new SQLException('odbc extension not loaded'); 54 55 $adapterclass = isset($dsninfo['adapter']) ? $dsninfo['adapter'] : null; 56 57 if (!$adapterclass) 58 $adapterclass = 'ODBCAdapter'; 59 else 60 $adapterclass .= 'Adapter'; 61 62 Creole::import('creole.drivers.odbc.adapters.' . $adapterclass); 63 $this->adapter = new $adapterclass(); 64 65 $this->dsn = $dsninfo; 66 $this->flags = $flags; 67 68 if ( !($this->flags & Creole::COMPAT_ASSOC_LOWER) && !$this->adapter->preservesColumnCase()) 69 { 70 trigger_error('Connection created without Creole::COMPAT_ASSOC_LOWER, ' . 71 'but driver does not support case preservation.', 72 E_USER_WARNING); 73 $this->flags != Creole::COMPAT_ASSOC_LOWER; 74 } 75 76 $persistent = ($flags & Creole::PERSISTENT) === Creole::PERSISTENT; 77 78 if ($dsninfo['database']) 79 $odbcdsn = $dsninfo['database']; 80 elseif ($dsninfo['hostspec']) 81 $odbcdsn = $dsninfo['hostspec']; 82 else 83 $odbcdsn = 'localhost'; 84 85 $user = @$dsninfo['username']; 86 $pw = @$dsninfo['password']; 87 88 $connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect'; 89 90 $conn = @$connect_function($odbcdsn, $user, $pw, SQL_CUR_USE_IF_NEEDED); 91 92 if (!is_resource($conn)) 93 throw new SQLException('connect failed', $this->nativeError(), $odbcdsn); 94 95 $this->dblink = $conn; 96 97 /** 98 * This prevents blob fields from being fetched when a row is loaded 99 * from a recordset. Clob fields however are loaded with up to 100 * 'odbc.defaultlrl' data. This should be the default anyway, but we'll 101 * set it here just to keep things consistent. 102 */ 103 @odbc_binmode(0, ODBC_BINMODE_PASSTHRU); 104 @odbc_longreadlen(0, ini_get('odbc.defaultlrl')); 105 } 106 107 /** 108 * @see Connection::close() 109 */ 110 public function close() 111 { 112 $ret = true; 113 114 $this->adapter = null; 115 $this->odbcresult = null; 116 117 if ($this->dblink !== null) 118 { 119 $ret = @odbc_close($this->dblink); 120 $this->dblink = null; 121 } 122 123 return $ret; 124 } 125 126 /** 127 * Shouldn't this be in ConnectionCommon.php? 128 */ 129 public function __destruct() 130 { 131 $this->close(); 132 } 133 134 /** 135 * Returns a formatted ODBC error string. 136 * @return string 137 */ 138 public function nativeError() 139 { 140 if ($this->dblink && is_resource($this->dblink)) 141 $errstr = '[' . @odbc_error($this->dblink) . '] ' . @odbc_errormsg($this->dblink); 142 else 143 $errstr = '[' . @odbc_error() . '] ' . @odbc_errormsg(); 144 145 return $errstr; 146 } 147 148 /** 149 * Returns driver-specific ODBCAdapter. 150 * @return ODBCAdapter 151 */ 152 public function getAdapter() 153 { 154 return $this->adapter; 155 } 156 157 /** 158 * @see Connection::getDatabaseInfo() 159 */ 160 public function getDatabaseInfo() 161 { 162 require_once 'creole/drivers/odbc/metadata/ODBCDatabaseInfo.php'; 163 return new ODBCDatabaseInfo($this); 164 } 165 166 /** 167 * @see Connection::getIdGenerator() 168 */ 169 public function getIdGenerator() 170 { 171 return $this->adapter->getIdGenerator($this); 172 } 173 174 /** 175 * Creates the appropriate ResultSet 176 * @return ResultSet 177 */ 178 public function createResultSet($odbcresult, $fetchmode) 179 { 180 return $this->adapter->createResultSet($this, $odbcresult, $fetchmode); 181 } 182 183 /** 184 * @see Connection::prepareStatement() 185 */ 186 public function prepareStatement($sql) 187 { 188 require_once 'creole/drivers/odbc/ODBCPreparedStatement.php'; 189 return new ODBCPreparedStatement($this, $sql); 190 } 191 192 /** 193 * @see Connection::createStatement() 194 */ 195 public function createStatement() 196 { 197 require_once 'creole/drivers/odbc/ODBCStatement.php'; 198 return new ODBCStatement($this); 199 } 200 201 /** 202 * @todo To be implemented 203 * @see Connection::prepareCall() 204 */ 205 public function prepareCall($sql) 206 { 207 throw new SQLException('Stored procedures not currently implemented.'); 208 } 209 210 /** 211 * @see Connection::applyLimit() 212 */ 213 public function applyLimit(&$sql, $offset, $limit) 214 { 215 if ($this->adapter->hasLimitOffset()) 216 $this->adapter->applyLimit($sql, $offset, $limit); 217 } 218 219 /** 220 * @see Connection::executeQuery() 221 */ 222 public function executeQuery($sql, $fetchmode = null) 223 { 224 if ($this->odbcresult) 225 $this->odbcresult = null; 226 227 $r = @odbc_exec($this->dblink, $sql); 228 229 if ($r === false) 230 throw new SQLException('Could not execute query', $this->nativeError(), $sql); 231 232 $this->odbcresult = new ODBCResultResource($r); 233 234 return $this->createResultSet($this->odbcresult, $fetchmode); 235 } 236 237 /** 238 * @see Connection::executeUpdate() 239 */ 240 public function executeUpdate($sql) 241 { 242 if ($this->odbcresult) 243 $this->odbcresult = null; 244 245 $r = @odbc_exec($this->dblink, $sql); 246 247 if ($r === false) 248 throw new SQLException('Could not execute update', $this->nativeError(), $sql); 249 250 $this->odbcresult = new ODBCResultResource($r); 251 252 return $this->getUpdateCount(); 253 } 254 255 /** 256 * Start a database transaction. 257 * @throws SQLException 258 * @return void 259 */ 260 protected function beginTrans() 261 { 262 if ($this->adapter->supportsTransactions()) { 263 @odbc_autocommit($this->dblink, false); 264 if (odbc_error($this->dblink) == 'S1C00') { 265 throw new SQLException('Could not begin transaction', $this->nativeError()); 266 } 267 } 268 } 269 270 /** 271 * Commit the current transaction. 272 * @throws SQLException 273 * @return void 274 */ 275 protected function commitTrans() 276 { 277 if ($this->adapter->supportsTransactions()) { 278 $result = @odbc_commit($this->dblink); 279 if (!$result) { 280 throw new SQLException('Could not commit transaction', $this->nativeError()); 281 } 282 @odbc_autocommit($this->dblink, true); 283 if (odbc_error($this->dblink) == 'S1C00') { 284 throw new SQLException('Could not commit transaction (autocommit failed)', $this->nativeError()); 285 } 286 } 287 } 288 289 /** 290 * Roll back (undo) the current transaction. 291 * @throws SQLException 292 * @return void 293 */ 294 protected function rollbackTrans() 295 { 296 if ($this->adapter->supportsTransactions()) { 297 $result = @odbc_rollback($this->dblink); 298 if (!$result) { 299 throw new SQLException('Could not rollback transaction', $this->nativeError()); 300 } 301 @odbc_autocommit($this->dblink, true); 302 if (odbc_error($this->dblink) == 'S1C00') { 303 throw new SQLException('Could not rollback transaction (autocommit failed)', $this->nativeError()); 304 } 305 } 306 } 307 308 /** 309 * @see Connection::getUpdateCount() 310 */ 311 public function getUpdateCount() 312 { 313 if ($this->odbcresult === null) 314 return 0; 315 316 $n = @odbc_num_rows($this->odbcresult->getHandle()); 317 318 if ($n == -1) 319 throw new SQLException('Could not retrieve update count', $this->nativeError()); 320 321 return (int) $n; 322 } 323 324 } 325 326 /** 327 * This is a simple wrapper class to manage the lifetime of an ODBC result resource 328 * (returned by odbc_exec(), odbc_execute(), etc.) We use a separate class because 329 * the resource can be shared by both ODBCConnection and an ODBCResultSet at the 330 * same time. ODBCConnection hangs on to the last result resource to be used in 331 * its getUpdateCount() method. It also passes this resource to new instances of 332 * ODBCResultSet. At some point the resource has to be cleaned up via 333 * odbc_free_result(). Using this class as a wrapper, we can pass around multiple 334 * references to the same resource. PHP's reference counting mechanism will clean 335 * up the resource when its no longer used via ODBCResultResource::__destruct(). 336 * @package creole.drivers.odbc 337 */ 338 class ODBCResultResource 339 { 340 /** 341 * @var resource ODBC result resource returned by {@link odbc_exec()}/{@link odbc_execute()}. 342 */ 343 protected $handle = null; 344 345 public function __construct($handle) 346 { 347 if (is_resource($handle)) 348 $this->handle = $handle; 349 } 350 351 public function __destruct() 352 { 353 if ($this->handle !== null) 354 @odbc_free_result($this->handle); 355 } 356 357 public function getHandle() 358 { 359 return $this->handle; 360 } 361 362 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |