[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/vendor/creole/drivers/odbc/ -> ODBCConnection.php (source)

   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  }


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7