mirror of
https://github.com/atlanticbiomedical/portal-legacy.git
synced 2025-07-02 01:47:28 -04:00
initial commit
This commit is contained in:
218
lib/symfony/vendor/creole/drivers/odbc/ODBCCachedResultSet.php
vendored
Executable file
218
lib/symfony/vendor/creole/drivers/odbc/ODBCCachedResultSet.php
vendored
Executable file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCCachedResultSet.php,v 1.2 2005/04/01 17:04:00 dlawson_mi Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/odbc/ODBCResultSetCommon.php';
|
||||
require_once 'creole/drivers/odbc/ODBCTypes.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of a cached ResultSet.
|
||||
*
|
||||
* In addition to limit/offset emulation, this class implements a resultset
|
||||
* cache. This can be useful as a workaround for some ODBC drivers which lack
|
||||
* support for reverse/absolute cursor scrolling, etc.
|
||||
*
|
||||
* This class will cache rows _on-demand_. So if you only read the first couple
|
||||
* rows of a result, then only those rows will be cached. However, note that if
|
||||
* you call getRecordCount() or last(), the class must read and cache all
|
||||
* available records.
|
||||
*
|
||||
* The offset / limit variables are also taken into account when caching. Any
|
||||
* rows preceding the offset value will be skipped. Caching will stop once the
|
||||
* limit value is reached.
|
||||
*
|
||||
* To use this class, create a derived {@link ODBCAdapter} class which returns
|
||||
* an instance of ODBCCachedResultSet from the {@link ODBCAdapter::createResultSet()} method.
|
||||
* Specify the adapter via the query portion of the Connection URL:
|
||||
*
|
||||
* odbc://localhost/Driver=MySQL ODBC 3.51 Driver;Database=test?adapter=MySQL
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCCachedResultSet extends ODBCResultSetCommon implements ResultSet
|
||||
{
|
||||
/**
|
||||
* Record cache
|
||||
* @var array
|
||||
*/
|
||||
protected $recs = array();
|
||||
|
||||
/**
|
||||
* Tracks the last cursor position of the recordset.
|
||||
* @var integer
|
||||
*/
|
||||
protected $lastPos = -1;
|
||||
|
||||
/**
|
||||
* True if blobs/clobs should also be cached.
|
||||
* @var boolean
|
||||
*/
|
||||
protected $cacheLobs = false;
|
||||
|
||||
/**
|
||||
* @see ResultSet::__construct()
|
||||
*/
|
||||
public function __construct(Connection $conn, $result, $fetchmode = null, $cacheLobs = false)
|
||||
{
|
||||
parent::__construct($conn, $result, $fetchmode);
|
||||
|
||||
$this->cacheLobs = $cacheLobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCResultSetCommon::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
parent::close();
|
||||
$this->recs = null;
|
||||
$this->lastPos = -1;
|
||||
$this->cacheLobs = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches specified records up to and including the specified 1-based
|
||||
* record position. If -1 is specified, all records will be cached.
|
||||
* @param integer Maximum record position to cache.
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function loadCache($recPos = -1)
|
||||
{
|
||||
$rid = $this->result->getHandle();
|
||||
|
||||
$curRecs = count($this->recs);
|
||||
$totRecs = ($curRecs ? $this->offset + $curRecs : 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Is record already cached?
|
||||
if ($this->lastPos != -1 || ($recPos > -1 && $recPos <= $curRecs))
|
||||
return;
|
||||
|
||||
// Fetch row (no buffers copied yet).
|
||||
$rowNum = ++$totRecs;
|
||||
$result = @odbc_fetch_row($rid, $rowNum);
|
||||
|
||||
// All records cached?
|
||||
if ($result === false || ($this->limit > 0 && $curRecs+1 > $this->limit))
|
||||
{
|
||||
$this->lastPos = $curRecs;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore offset records.
|
||||
if ($totRecs <= $this->offset)
|
||||
continue;
|
||||
|
||||
// Load row array.
|
||||
$row = array();
|
||||
for ($i = 0, $n = @odbc_num_fields($rid); $i < $n; $i++)
|
||||
{
|
||||
$fldNum = $i+1;
|
||||
$row[$i] = odbc_result($rid, $fldNum);
|
||||
|
||||
// Cache lobs if necessary
|
||||
if ($this->cacheLobs)
|
||||
{
|
||||
ODBCTypes::loadTypeMap($this->conn);
|
||||
|
||||
$nativeType = @odbc_field_type($rid, $fldNum);
|
||||
$creoleType = ODBCTypes::getType($nativeType);
|
||||
|
||||
$isBlob = ($creoleType == CreoleTypes::BLOB ||
|
||||
$creoleType == CreoleTypes::LONGVARBINARY);
|
||||
|
||||
$isClob = ($creoleType == CreoleTypes::CLOB ||
|
||||
$creoleType == CreoleTypes::LONGVARCHAR);
|
||||
|
||||
if (($isBlob || $isClob) && $row[$i] !== null)
|
||||
{
|
||||
$binmode = ($isBlob ? ODBC_BINMODE_RETURN : ODBC_BINMODE_CONVERT);
|
||||
$curdata = $row[$i];
|
||||
$row[$i] = $this->readLobData($fldNum, $binmode, $curdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add record to cache.
|
||||
$this->recs[++$curRecs] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
$this->loadCache($rownum);
|
||||
|
||||
if ($rownum < 0 || $rownum > count($this->recs)+1)
|
||||
return false;
|
||||
|
||||
$this->cursorPos = $rownum;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
$this->loadCache(++$this->cursorPos);
|
||||
|
||||
if ($this->isAfterLast())
|
||||
{
|
||||
$this->afterLast();
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fields =& $this->checkFetchMode($this->recs[$this->cursorPos]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
function getRecordCount()
|
||||
{
|
||||
if ($this->lastPos == -1)
|
||||
$this->loadCache(-1);
|
||||
|
||||
return $this->lastPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::isAfterLast()
|
||||
*/
|
||||
public function isAfterLast()
|
||||
{
|
||||
// All records cached yet?
|
||||
if ($this->lastPos == -1)
|
||||
return false;
|
||||
|
||||
return ($this->cursorPos > $this->lastPos);
|
||||
}
|
||||
|
||||
}
|
362
lib/symfony/vendor/creole/drivers/odbc/ODBCConnection.php
vendored
Executable file
362
lib/symfony/vendor/creole/drivers/odbc/ODBCConnection.php
vendored
Executable file
@ -0,0 +1,362 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCConnection.php,v 1.6 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Connection.php';
|
||||
require_once 'creole/common/ConnectionCommon.php';
|
||||
require_once 'creole/drivers/odbc/adapters/ODBCAdapter.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of Connection.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.6 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCConnection extends ConnectionCommon implements Connection {
|
||||
|
||||
/**
|
||||
* Implements driver-specific behavior
|
||||
* @var ODBCAdapter
|
||||
*/
|
||||
protected $adapter = null;
|
||||
|
||||
/**
|
||||
* Last ODBC result resource from executeQuery/executeUpdate. Used in getUpdateCount()
|
||||
* @var ODBCResultResource
|
||||
*/
|
||||
protected $odbcresult = null;
|
||||
|
||||
/**
|
||||
* @see Connection::connect()
|
||||
*/
|
||||
public function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
if (!function_exists('odbc_connect'))
|
||||
throw new SQLException('odbc extension not loaded');
|
||||
|
||||
$adapterclass = isset($dsninfo['adapter']) ? $dsninfo['adapter'] : null;
|
||||
|
||||
if (!$adapterclass)
|
||||
$adapterclass = 'ODBCAdapter';
|
||||
else
|
||||
$adapterclass .= 'Adapter';
|
||||
|
||||
Creole::import('creole.drivers.odbc.adapters.' . $adapterclass);
|
||||
$this->adapter = new $adapterclass();
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
if ( !($this->flags & Creole::COMPAT_ASSOC_LOWER) && !$this->adapter->preservesColumnCase())
|
||||
{
|
||||
trigger_error('Connection created without Creole::COMPAT_ASSOC_LOWER, ' .
|
||||
'but driver does not support case preservation.',
|
||||
E_USER_WARNING);
|
||||
$this->flags != Creole::COMPAT_ASSOC_LOWER;
|
||||
}
|
||||
|
||||
$persistent = ($flags & Creole::PERSISTENT) === Creole::PERSISTENT;
|
||||
|
||||
if ($dsninfo['database'])
|
||||
$odbcdsn = $dsninfo['database'];
|
||||
elseif ($dsninfo['hostspec'])
|
||||
$odbcdsn = $dsninfo['hostspec'];
|
||||
else
|
||||
$odbcdsn = 'localhost';
|
||||
|
||||
$user = @$dsninfo['username'];
|
||||
$pw = @$dsninfo['password'];
|
||||
|
||||
$connect_function = $persistent ? 'odbc_pconnect' : 'odbc_connect';
|
||||
|
||||
$conn = @$connect_function($odbcdsn, $user, $pw, SQL_CUR_USE_IF_NEEDED);
|
||||
|
||||
if (!is_resource($conn))
|
||||
throw new SQLException('connect failed', $this->nativeError(), $odbcdsn);
|
||||
|
||||
$this->dblink = $conn;
|
||||
|
||||
/**
|
||||
* This prevents blob fields from being fetched when a row is loaded
|
||||
* from a recordset. Clob fields however are loaded with up to
|
||||
* 'odbc.defaultlrl' data. This should be the default anyway, but we'll
|
||||
* set it here just to keep things consistent.
|
||||
*/
|
||||
@odbc_binmode(0, ODBC_BINMODE_PASSTHRU);
|
||||
@odbc_longreadlen(0, ini_get('odbc.defaultlrl'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$ret = true;
|
||||
|
||||
$this->adapter = null;
|
||||
$this->odbcresult = null;
|
||||
|
||||
if ($this->dblink !== null)
|
||||
{
|
||||
$ret = @odbc_close($this->dblink);
|
||||
$this->dblink = null;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shouldn't this be in ConnectionCommon.php?
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted ODBC error string.
|
||||
* @return string
|
||||
*/
|
||||
public function nativeError()
|
||||
{
|
||||
if ($this->dblink && is_resource($this->dblink))
|
||||
$errstr = '[' . @odbc_error($this->dblink) . '] ' . @odbc_errormsg($this->dblink);
|
||||
else
|
||||
$errstr = '[' . @odbc_error() . '] ' . @odbc_errormsg();
|
||||
|
||||
return $errstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns driver-specific ODBCAdapter.
|
||||
* @return ODBCAdapter
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/odbc/metadata/ODBCDatabaseInfo.php';
|
||||
return new ODBCDatabaseInfo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
return $this->adapter->getIdGenerator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the appropriate ResultSet
|
||||
* @return ResultSet
|
||||
*/
|
||||
public function createResultSet($odbcresult, $fetchmode)
|
||||
{
|
||||
return $this->adapter->createResultSet($this, $odbcresult, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCPreparedStatement.php';
|
||||
return new ODBCPreparedStatement($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCStatement.php';
|
||||
return new ODBCStatement($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo To be implemented
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall($sql)
|
||||
{
|
||||
throw new SQLException('Stored procedures not currently implemented.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ($this->adapter->hasLimitOffset())
|
||||
$this->adapter->applyLimit($sql, $offset, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeQuery()
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
if ($this->odbcresult)
|
||||
$this->odbcresult = null;
|
||||
|
||||
$r = @odbc_exec($this->dblink, $sql);
|
||||
|
||||
if ($r === false)
|
||||
throw new SQLException('Could not execute query', $this->nativeError(), $sql);
|
||||
|
||||
$this->odbcresult = new ODBCResultResource($r);
|
||||
|
||||
return $this->createResultSet($this->odbcresult, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::executeUpdate()
|
||||
*/
|
||||
public function executeUpdate($sql)
|
||||
{
|
||||
if ($this->odbcresult)
|
||||
$this->odbcresult = null;
|
||||
|
||||
$r = @odbc_exec($this->dblink, $sql);
|
||||
|
||||
if ($r === false)
|
||||
throw new SQLException('Could not execute update', $this->nativeError(), $sql);
|
||||
|
||||
$this->odbcresult = new ODBCResultResource($r);
|
||||
|
||||
return $this->getUpdateCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
if ($this->adapter->supportsTransactions()) {
|
||||
@odbc_autocommit($this->dblink, false);
|
||||
if (odbc_error($this->dblink) == 'S1C00') {
|
||||
throw new SQLException('Could not begin transaction', $this->nativeError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
if ($this->adapter->supportsTransactions()) {
|
||||
$result = @odbc_commit($this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not commit transaction', $this->nativeError());
|
||||
}
|
||||
@odbc_autocommit($this->dblink, true);
|
||||
if (odbc_error($this->dblink) == 'S1C00') {
|
||||
throw new SQLException('Could not commit transaction (autocommit failed)', $this->nativeError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
if ($this->adapter->supportsTransactions()) {
|
||||
$result = @odbc_rollback($this->dblink);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not rollback transaction', $this->nativeError());
|
||||
}
|
||||
@odbc_autocommit($this->dblink, true);
|
||||
if (odbc_error($this->dblink) == 'S1C00') {
|
||||
throw new SQLException('Could not rollback transaction (autocommit failed)', $this->nativeError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getUpdateCount()
|
||||
*/
|
||||
public function getUpdateCount()
|
||||
{
|
||||
if ($this->odbcresult === null)
|
||||
return 0;
|
||||
|
||||
$n = @odbc_num_rows($this->odbcresult->getHandle());
|
||||
|
||||
if ($n == -1)
|
||||
throw new SQLException('Could not retrieve update count', $this->nativeError());
|
||||
|
||||
return (int) $n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a simple wrapper class to manage the lifetime of an ODBC result resource
|
||||
* (returned by odbc_exec(), odbc_execute(), etc.) We use a separate class because
|
||||
* the resource can be shared by both ODBCConnection and an ODBCResultSet at the
|
||||
* same time. ODBCConnection hangs on to the last result resource to be used in
|
||||
* its getUpdateCount() method. It also passes this resource to new instances of
|
||||
* ODBCResultSet. At some point the resource has to be cleaned up via
|
||||
* odbc_free_result(). Using this class as a wrapper, we can pass around multiple
|
||||
* references to the same resource. PHP's reference counting mechanism will clean
|
||||
* up the resource when its no longer used via ODBCResultResource::__destruct().
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCResultResource
|
||||
{
|
||||
/**
|
||||
* @var resource ODBC result resource returned by {@link odbc_exec()}/{@link odbc_execute()}.
|
||||
*/
|
||||
protected $handle = null;
|
||||
|
||||
public function __construct($handle)
|
||||
{
|
||||
if (is_resource($handle))
|
||||
$this->handle = $handle;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->handle !== null)
|
||||
@odbc_free_result($this->handle);
|
||||
}
|
||||
|
||||
public function getHandle()
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
}
|
118
lib/symfony/vendor/creole/drivers/odbc/ODBCIdGenerator.php
vendored
Executable file
118
lib/symfony/vendor/creole/drivers/odbc/ODBCIdGenerator.php
vendored
Executable file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
require_once 'creole/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* ODBC IdGenerator implimenation.
|
||||
*
|
||||
* NOTE: I tried keeping the SQL as basic as possible in this class.
|
||||
* If you need something more optimized, derive your own IdGenerator
|
||||
* and use {@link ODBCAdapter::getIdGenerator()} to use it.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCIdGenerator implements IdGenerator {
|
||||
|
||||
/** Connection object that instantiated this class */
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* Creates a new IdGenerator class, saves passed connection for use
|
||||
* later by getId() method.
|
||||
* @param Connection $conn
|
||||
*/
|
||||
public function __construct(Connection $conn)
|
||||
{
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isBeforeInsert()
|
||||
*/
|
||||
public function isBeforeInsert()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::isAfterInsert()
|
||||
*/
|
||||
public function isAfterInsert()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getIdMethod()
|
||||
*/
|
||||
public function getIdMethod()
|
||||
{
|
||||
return self::SEQUENCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IdGenerator::getId()
|
||||
*/
|
||||
public function getId($seqname = null)
|
||||
{
|
||||
if ($seqname === null)
|
||||
throw new SQLException('You must specify the sequence name when calling getId() method.');
|
||||
|
||||
$triedcreate = false;
|
||||
|
||||
while (1)
|
||||
{
|
||||
try
|
||||
{
|
||||
$n = $this->conn->executeUpdate("UPDATE $seqname SET id = id + 1", ResultSet::FETCHMODE_NUM);
|
||||
|
||||
if ($n == 0)
|
||||
throw new SQLException('Failed to update IdGenerator id', $this->conn->nativeError());
|
||||
|
||||
$rs = $this->conn->executeQuery("SELECT id FROM $seqname", ResultSet::FETCHMODE_NUM);
|
||||
}
|
||||
catch (SQLException $e)
|
||||
{
|
||||
//$odbcerr = odbc_error($this->conn->getResource());
|
||||
|
||||
if ($triedcreate)// || ($odbcerr != 'S0000' && $odbcerr != 'S0002'))
|
||||
throw $e;
|
||||
|
||||
$this->drop($seqname, true);
|
||||
$this->create($seqname);
|
||||
$triedcreate = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$rs->first();
|
||||
|
||||
return $rs->getInt(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the sequence emulation table.
|
||||
*/
|
||||
public function create($seqname)
|
||||
{
|
||||
$this->conn->executeUpdate("CREATE TABLE $seqname ( id numeric(19,0) NOT NULL )");
|
||||
$this->conn->executeUpdate("INSERT INTO $seqname ( id ) VALUES ( 0 )");
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the sequence emulation table.
|
||||
*/
|
||||
public function drop($seqname, $ignoreerrs = false)
|
||||
{
|
||||
try {
|
||||
$this->conn->executeUpdate("DROP TABLE $seqname");
|
||||
} catch (Exception $e) {
|
||||
if (!$ignoreerrs) throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
246
lib/symfony/vendor/creole/drivers/odbc/ODBCPreparedStatement.php
vendored
Executable file
246
lib/symfony/vendor/creole/drivers/odbc/ODBCPreparedStatement.php
vendored
Executable file
@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCPreparedStatement.php,v 1.4 2005/11/13 01:29:01 gamr Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
require_once 'creole/util/Lob.php';
|
||||
|
||||
/**
|
||||
* ODBC specific PreparedStatement functions.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.4 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCPreparedStatement extends PreparedStatementCommon implements PreparedStatement
|
||||
{
|
||||
/**
|
||||
* This does nothing since ODBC natively supports prepared statements.
|
||||
* @see PreparedStatementCommon::replaceParams()
|
||||
*/
|
||||
protected function replaceParams()
|
||||
{
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
return parent::replaceParams();
|
||||
else
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to call native ODBC prepare/execute functions.
|
||||
*/
|
||||
protected function _execute($sql, $params, $fetchmode, $isupdate)
|
||||
{
|
||||
if ($this->resultSet)
|
||||
{
|
||||
$this->resultSet->close();
|
||||
$this->resultSet = null;
|
||||
}
|
||||
|
||||
$this->updateCount = null;
|
||||
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
{
|
||||
$stmt = @odbc_exec($this->conn->getResource(), $sql);
|
||||
$ret = ($stmt !== false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Trim surrounding quotes added from default set methods.
|
||||
// Exception: for LOB-based parameters, odbc_execute() will
|
||||
// accept a filename surrounded by single-quotes.
|
||||
foreach ($this->boundInVars as $idx => $var)
|
||||
{
|
||||
if ($var instanceof Lob)
|
||||
{
|
||||
$file = ($isupdate ? $var->getInputFile() : $var->getOutputFile());
|
||||
$this->boundInVars[$idx] = "'$file'";
|
||||
}
|
||||
else if (is_string($var))
|
||||
{
|
||||
$this->boundInVars[$idx] = trim($var, "\"\'");
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = @odbc_prepare($this->conn->getResource(), $sql);
|
||||
|
||||
if ($stmt === FALSE)
|
||||
throw new SQLException('Could not prepare query', $this->conn->nativeError(), $sql);
|
||||
|
||||
$ret = @odbc_execute($stmt, $this->boundInVars);
|
||||
}
|
||||
|
||||
if ($ret === FALSE)
|
||||
{
|
||||
@odbc_free_result($stmt);
|
||||
throw new SQLException('Could not execute query', $this->conn->nativeError(), $sql);
|
||||
}
|
||||
|
||||
return $this->conn->createResultSet(new ODBCResultResource($stmt), $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::executeQuery()
|
||||
*/
|
||||
public function executeQuery()
|
||||
{
|
||||
switch (func_num_args()) {
|
||||
case 2:
|
||||
list($params, $fetchmode) = func_get_args();
|
||||
if (!is_array($params)) {
|
||||
unset($params);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
$params = null;
|
||||
list($fetchmode) = func_get_args();
|
||||
break;
|
||||
case 0:
|
||||
$params = null;
|
||||
$fetchmode = null;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set any params passed directly
|
||||
if (isset($params)) {
|
||||
for($i=0,$cnt=count($params); $i < $cnt; $i++) {
|
||||
$this->set($i+1, $params[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = $this->replaceParams();
|
||||
|
||||
if ($this->conn->getAdapter()->hasLimitOffset())
|
||||
{
|
||||
if ($this->limit > 0 || $this->offset > 0)
|
||||
$this->conn->applyLimit($sql, $this->offset, $this->limit);
|
||||
}
|
||||
|
||||
$this->resultSet = $this->_execute($sql, $params, $fetchmode, false);
|
||||
|
||||
if (!$this->conn->getAdapter()->hasLimitOffset())
|
||||
{
|
||||
$this->resultSet->_setOffset($this->offset);
|
||||
$this->resultSet->_setLimit($this->limit);
|
||||
}
|
||||
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::executeUpdate()
|
||||
*/
|
||||
public function executeUpdate($params = null)
|
||||
{
|
||||
// Set any params passed directly
|
||||
if ($params) {
|
||||
for($i=0,$cnt=count($params); $i < $cnt; $i++) {
|
||||
$this->set($i+1, $params[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = $this->replaceParams();
|
||||
$this->_execute($sql, $params, 0, true);
|
||||
$this->updateCount = $this->conn->getUpdateCount();
|
||||
|
||||
return $this->updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatementCommon::escape()
|
||||
*/
|
||||
protected function escape($str)
|
||||
{
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
return $this->conn->getAdapter()->escape($str);
|
||||
|
||||
// Nothing to do here. odbc_execute() takes care of escaping strings.
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setNull()
|
||||
*/
|
||||
function setNull($paramIndex)
|
||||
{
|
||||
$this->sql_cache_valid = false;
|
||||
$this->boundInVars[$paramIndex] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setBlob()
|
||||
*/
|
||||
function setBlob($paramIndex, $blob)
|
||||
{
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
return parent::setBlob($paramIndex, $blob);
|
||||
|
||||
$this->sql_cache_valid = false;
|
||||
if ($blob === null)
|
||||
{
|
||||
$this->setNull($paramIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($blob instanceof Blob)
|
||||
{
|
||||
if ($blob->isFromFile() && !$blob->isModified())
|
||||
{
|
||||
$this->boundInVars[$paramIndex] = $blob;
|
||||
return;
|
||||
}
|
||||
|
||||
$blob = $blob->__toString();
|
||||
}
|
||||
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($blob) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatement::setClob()
|
||||
*/
|
||||
function setClob($paramIndex, $clob)
|
||||
{
|
||||
if ($this->conn->getAdapter()->emulatePrepareStmt())
|
||||
return parent::setClob($paramIndex, $clob);
|
||||
|
||||
$this->sql_cache_valid = false;
|
||||
if ($clob === null)
|
||||
{
|
||||
$this->setNull($paramIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($clob instanceof Clob)
|
||||
{
|
||||
if ($clob->isFromFile() && !$clob->isModified())
|
||||
{
|
||||
$this->boundInVars[$paramIndex] = $clob;
|
||||
return;
|
||||
}
|
||||
|
||||
$clob = $clob->__toString();
|
||||
}
|
||||
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->escape($clob) . "'";
|
||||
}
|
||||
|
||||
}
|
209
lib/symfony/vendor/creole/drivers/odbc/ODBCResultSet.php
vendored
Executable file
209
lib/symfony/vendor/creole/drivers/odbc/ODBCResultSet.php
vendored
Executable file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCResultSet.php,v 1.2 2005/04/01 17:10:42 dlawson_mi Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/odbc/ODBCResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of ResultSet.
|
||||
*
|
||||
* If the current ODBC driver does not support LIMIT or OFFSET natively,
|
||||
* the methods in here perform some adjustments and extra checking to make
|
||||
* sure that this behaves the same as RDBMS drivers using native OFFSET/LIMIT.
|
||||
*
|
||||
* This class also emulates a row count if the driver is not capable of
|
||||
* providing one natively.
|
||||
*
|
||||
* NOTE: This class only works with drivers that support absolute cursor
|
||||
* positioning (SQL_FETCH_DIRECTION = SQL_FD_FETCH_ABSOLUTE). If the
|
||||
* driver you are using does not support reverse/absolute cursor
|
||||
* scrolling, you should use the {@link ODBCCachedResultSet} class instead.
|
||||
* See the documentation for ODBCCachedResultSet for instructions on how
|
||||
* to use it.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCResultSet extends ODBCResultSetCommon implements ResultSet
|
||||
{
|
||||
/**
|
||||
* Number of rows in resultset.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $numRows = -1;
|
||||
|
||||
/**
|
||||
* True if ODBC driver supports odbc_num_rows().
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $hasRowCount = false;
|
||||
|
||||
/**
|
||||
* @see ResultSet::__construct()
|
||||
*/
|
||||
public function __construct(Connection $conn, $result, $fetchmode = null)
|
||||
{
|
||||
parent::__construct($conn, $result, $fetchmode);
|
||||
|
||||
/**
|
||||
* Some ODBC drivers appear not to handle odbc_num_rows() very well when
|
||||
* more than one result handle is active at once. For example, the MySQL
|
||||
* ODBC driver always returns the number of rows for the last executed
|
||||
* result. For this reason, we'll store the row count here.
|
||||
*
|
||||
* Note also that many ODBC drivers do not support this method. In this
|
||||
* case, getRecordCount() will perform a manual count.
|
||||
*/
|
||||
$this->numRows = @odbc_num_rows($result->getHandle());
|
||||
$this->hasRowCount = $this->numRows != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCResultSetCommon::close()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
parent::close();
|
||||
$numRows = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
if ($rownum < 0 || $this->limit > 0 && $rownum > $this->limit)
|
||||
return false;
|
||||
|
||||
$this->cursorPos = $rownum;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->cursorPos++;
|
||||
|
||||
if ($this->limit > 0 && $this->cursorPos > $this->limit) {
|
||||
$this->cursorPos = $this->limit+1;
|
||||
return false;
|
||||
}
|
||||
|
||||
$rowNum = $this->offset + $this->cursorPos;
|
||||
$fields = null;
|
||||
|
||||
$cols = @odbc_fetch_into($this->result->getHandle(), $fields, $rowNum);
|
||||
|
||||
if ($cols === false) {
|
||||
$this->cursorPos = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fields =& $this->checkFetchMode($fields);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::isAfterLast()
|
||||
*/
|
||||
public function isAfterLast()
|
||||
{
|
||||
// Force calculation of last record pos.
|
||||
if ($this->cursorPos == -1)
|
||||
$this->getRecordCount();
|
||||
|
||||
return parent::isAfterLast();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
function getRecordCount()
|
||||
{
|
||||
if ($this->hasRowCount)
|
||||
{
|
||||
// Use driver row count if provided.
|
||||
$numRows = $this->numRows - $this->offset;
|
||||
|
||||
if ($this->limit > 0 && $numRows > $this->limit)
|
||||
$numRows = $this->limit;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do manual row count if driver doesn't provide one.
|
||||
if ($this->numRows == -1)
|
||||
{
|
||||
$this->numRows = 0;
|
||||
$this->beforeFirst();
|
||||
|
||||
while($this->next())
|
||||
$this->numRows++;
|
||||
}
|
||||
|
||||
$numRows = $this->numRows;
|
||||
}
|
||||
|
||||
// Cursor pos is -1 when an attempt to fetch past the last row was made
|
||||
// (or a fetch error occured).
|
||||
|
||||
if ($this->cursorPos == -1)
|
||||
$this->cursorPos = $numRows+1;
|
||||
|
||||
return $numRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getBlob()
|
||||
*/
|
||||
public function getBlob($column)
|
||||
{
|
||||
require_once 'creole/util/Blob.php';
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
$data = $this->readLobData($column, ODBC_BINMODE_RETURN, $this->fields[$idx]);
|
||||
if (!$data) { return null; }
|
||||
$b = new Blob();
|
||||
$b->setContents($data);
|
||||
return $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getClob()
|
||||
*/
|
||||
public function getClob($column)
|
||||
{
|
||||
require_once 'creole/util/Clob.php';
|
||||
$idx = (is_int($column) ? $column - 1 : $column);
|
||||
if (!array_key_exists($idx, $this->fields)) { throw new SQLException("Invalid resultset column: " . $column); }
|
||||
$data = $this->readLobData($column, ODBC_BINMODE_CONVERT, $this->fields[$idx]);
|
||||
if (!$data) { return null; }
|
||||
$c = new Clob();
|
||||
$c->setContents($data);
|
||||
return $c;
|
||||
}
|
||||
|
||||
}
|
188
lib/symfony/vendor/creole/drivers/odbc/ODBCResultSetCommon.php
vendored
Executable file
188
lib/symfony/vendor/creole/drivers/odbc/ODBCResultSetCommon.php
vendored
Executable file
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCResultSetCommon.php,v 1.3 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/ResultSet.php';
|
||||
require_once 'creole/common/ResultSetCommon.php';
|
||||
|
||||
/**
|
||||
* Base class for ODBC implementation of ResultSet.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
abstract class ODBCResultSetCommon extends ResultSetCommon
|
||||
{
|
||||
/**
|
||||
* Offset at which to start reading rows (for emulated offset).
|
||||
* @var int
|
||||
*/
|
||||
protected $offset = 0;
|
||||
|
||||
/**
|
||||
* Maximum rows to retrieve, or 0 if all (for emulated limit).
|
||||
* @var int
|
||||
*/
|
||||
protected $limit = 0;
|
||||
|
||||
/**
|
||||
* @see ResultSet::__construct()
|
||||
*/
|
||||
public function __construct(Connection $conn, $result, $fetchmode = null)
|
||||
{
|
||||
parent::__construct($conn, $result, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->result = null;
|
||||
$this->conn = null;
|
||||
$this->fetchmode = null;
|
||||
$this->cursorPos = 0;
|
||||
$this->fields = null;
|
||||
$this->lowerAssocCase = false;
|
||||
$this->limit = 0;
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function exists to set offset after ResultSet is instantiated.
|
||||
* This function should be "protected" in Java sense: only available to classes in package.
|
||||
* THIS METHOD SHOULD NOT BE CALLED BY ANYTHING EXCEPTION DRIVER CLASSES.
|
||||
* @param int $offset New offset.
|
||||
* @access protected
|
||||
*/
|
||||
public function _setOffset($offset)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function exists to set limit after ResultSet is instantiated.
|
||||
* This function should be "protected" in Java sense: only available to classes in package.
|
||||
* THIS METHOD SHOULD NOT BE CALLED BY ANYTHING EXCEPTION DRIVER CLASSES.
|
||||
* @param int $limit New limit.
|
||||
* @access protected
|
||||
*/
|
||||
public function _setLimit($limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* If fetchmode is FETCHMODE_ASSOC, returns the 1-based field index number
|
||||
* for the specified column name. Otherwise returns 0 (false).
|
||||
* @return int
|
||||
*/
|
||||
function getFieldNum($colname)
|
||||
{
|
||||
$fieldnum = 0;
|
||||
|
||||
if ($this->fetchmode == ResultSet::FETCHMODE_ASSOC)
|
||||
{
|
||||
$keys = array_keys($this->fields);
|
||||
$fieldnum = array_search($colname, $keys);
|
||||
}
|
||||
|
||||
return $fieldnum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in any unread LOB data. For long char fields, we may already
|
||||
* have up to odbc_longreadlen() bytes in the buffer. These are passed
|
||||
* in via the $curdata parm. For long binary fields, no data is read
|
||||
* initially since odbc_binmode() is set to ODBC_BINMODE_PASSTHRU.
|
||||
* This method adjusts the binmode and longreadlen to finish reading
|
||||
* these datatypes into the buffer. Returns a string with the complete
|
||||
* contents.
|
||||
*
|
||||
* @param int|string $column Column index or name to read data from.
|
||||
* @param int $binmode ODBC_BINMODE_RETURN for binary data, ODBC_BINMODE_CONVERT for char data.
|
||||
* @param string $curdata Existing LOB data already in buffer.
|
||||
* @return string
|
||||
*/
|
||||
protected function readLobData($column, $binmode, $curdata = null)
|
||||
{
|
||||
// Retrieve field num
|
||||
$fldNum = (is_int($column) ? $column : getFieldNum($column));
|
||||
|
||||
$data = $curdata;
|
||||
$newdata = null;
|
||||
|
||||
// Adjust binmode and longreadlen
|
||||
odbc_binmode($this->result->getHandle(), $binmode);
|
||||
odbc_longreadlen($this->result->getHandle(), 4096);
|
||||
|
||||
while (1)
|
||||
{
|
||||
$newdata = odbc_result($this->result->getHandle(), $fldNum);
|
||||
|
||||
if ($newdata === false)
|
||||
break;
|
||||
else
|
||||
$data .= $newdata;
|
||||
}
|
||||
|
||||
// Restore the default binmode and longreadlen
|
||||
odbc_binmode($this->result->getHandle(), ODBC_BINMODE_PASSTHRU);
|
||||
odbc_longreadlen($this->result->getHandle(), ini_get('odbc.defaultlrl'));
|
||||
|
||||
// The ODBC driver I use seems to return a string with an escaped
|
||||
// null char at the end for clob data.
|
||||
$data = rtrim($data, "\x0");
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts row fields to names if FETCHMODE_ASSOC is set.
|
||||
*
|
||||
* @param array& Row to convert.
|
||||
*
|
||||
* @return array& Converted row.
|
||||
*/
|
||||
protected function checkFetchMode(&$row)
|
||||
{
|
||||
if ($this->fetchmode == ResultSet::FETCHMODE_ASSOC)
|
||||
{
|
||||
$newrow = array();
|
||||
|
||||
for ($i = 0, $n = count($row); $i < $n; $i++)
|
||||
{
|
||||
$colname = @odbc_field_name($this->result->getHandle(), $i+1);
|
||||
|
||||
if ($this->lowerAssocCase) {
|
||||
$colname = strtolower($colname);
|
||||
}
|
||||
|
||||
$newrow[$colname] = $row[$i];
|
||||
}
|
||||
|
||||
$row =& $newrow;
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
}
|
64
lib/symfony/vendor/creole/drivers/odbc/ODBCStatement.php
vendored
Executable file
64
lib/symfony/vendor/creole/drivers/odbc/ODBCStatement.php
vendored
Executable file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCStatement.php,v 1.1 2004/07/27 23:08:30 hlellelid Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/Statement.php';
|
||||
require_once 'creole/common/StatementCommon.php';
|
||||
|
||||
/**
|
||||
* ODBC Statement
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCStatement extends StatementCommon implements Statement
|
||||
{
|
||||
/**
|
||||
* @see Statement::executeQuery()
|
||||
*/
|
||||
public function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
if ($this->resultSet)
|
||||
{
|
||||
$this->resultSet->close();
|
||||
$this->resultSet = null;
|
||||
}
|
||||
|
||||
$this->updateCount = null;
|
||||
|
||||
if ($this->conn->getAdapter()->hasLimitOffset())
|
||||
{
|
||||
if ($this->limit > 0 || $this->offset > 0)
|
||||
$this->conn->applyLimit($sql, $this->offset, $this->limit);
|
||||
}
|
||||
|
||||
$this->resultSet = $this->conn->executeQuery($sql, $fetchmode);
|
||||
|
||||
if (!$this->conn->getAdapter()->hasLimitOffset())
|
||||
{
|
||||
$this->resultSet->_setOffset($this->offset);
|
||||
$this->resultSet->_setLimit($this->limit);
|
||||
}
|
||||
|
||||
return $this->resultSet;
|
||||
}
|
||||
|
||||
}
|
189
lib/symfony/vendor/creole/drivers/odbc/ODBCTypes.php
vendored
Executable file
189
lib/symfony/vendor/creole/drivers/odbc/ODBCTypes.php
vendored
Executable file
@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: ODBCTypes.php,v 1.1 2004/07/27 23:08:30 hlellelid Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/CreoleTypes.php';
|
||||
|
||||
/**
|
||||
* ODBC types / type map.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCTypes extends CreoleTypes {
|
||||
|
||||
/**
|
||||
* Map ODBC native types to Creole (JDBC) types.
|
||||
*/
|
||||
protected static $typeMap = null;
|
||||
|
||||
/**
|
||||
* Reverse mapping, created on demand.
|
||||
*/
|
||||
protected static $reverseMap = null;
|
||||
|
||||
/**
|
||||
* Loads the map of ODBC data types to Creole (JDBC) types.
|
||||
*
|
||||
* NOTE: This function cannot map DBMS-specific datatypes. If you use a
|
||||
* driver which implements DBMS-specific datatypes, you will need
|
||||
* to modify/extend this class to add the correct mapping.
|
||||
*/
|
||||
public static function loadTypeMap($conn = null)
|
||||
{
|
||||
if (self::$typeMap !== null && count(self::$typeMap) > 0)
|
||||
return;
|
||||
|
||||
if ($conn == null)
|
||||
throw new SQLException('No connection specified when loading ODBC type map.');
|
||||
|
||||
self::$typeMap = array();
|
||||
|
||||
$result = @odbc_gettypeinfo($conn->getResource());
|
||||
|
||||
if ($result === false)
|
||||
throw new SQLException('Failed to retrieve type info.', $conn->nativeError());
|
||||
|
||||
$rowNum = 1;
|
||||
|
||||
while (odbc_fetch_row($result, $rowNum++))
|
||||
{
|
||||
$odbctypeid = odbc_result($result, 'DATA_TYPE');
|
||||
$odbctypename = odbc_result($result, 'TYPE_NAME');
|
||||
|
||||
switch ($odbctypeid)
|
||||
{
|
||||
case SQL_CHAR:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::CHAR;
|
||||
break;
|
||||
case SQL_VARCHAR:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::VARCHAR;
|
||||
break;
|
||||
case SQL_LONGVARCHAR:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::LONGVARCHAR;
|
||||
break;
|
||||
case SQL_DECIMAL:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::DECIMAL;
|
||||
break;
|
||||
case SQL_NUMERIC:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::NUMERIC;
|
||||
break;
|
||||
case SQL_BIT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::BOOLEAN;
|
||||
break;
|
||||
case SQL_TINYINT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TINYINT;
|
||||
break;
|
||||
case SQL_SMALLINT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::SMALLINT;
|
||||
break;
|
||||
case SQL_INTEGER:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::INTEGER;
|
||||
break;
|
||||
case SQL_BIGINT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::BIGINT;
|
||||
break;
|
||||
case SQL_REAL:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::REAL;
|
||||
break;
|
||||
case SQL_FLOAT:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::FLOAT;
|
||||
break;
|
||||
case SQL_DOUBLE:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::DOUBLE;
|
||||
break;
|
||||
case SQL_BINARY:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::BINARY;
|
||||
break;
|
||||
case SQL_VARBINARY:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::VARBINARY;
|
||||
break;
|
||||
case SQL_LONGVARBINARY:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::LONGVARBINARY;
|
||||
break;
|
||||
case SQL_DATE:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::DATE;
|
||||
break;
|
||||
case SQL_TIME:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TIME;
|
||||
break;
|
||||
case SQL_TIMESTAMP:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TIMESTAMP;
|
||||
break;
|
||||
case SQL_TYPE_DATE:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::DATE;
|
||||
break;
|
||||
case SQL_TYPE_TIME:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TIME;
|
||||
break;
|
||||
case SQL_TYPE_TIMESTAMP:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::TIMESTAMP;
|
||||
break;
|
||||
default:
|
||||
self::$typeMap[$odbctypename] = CreoleTypes::OTHER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the generic Creole (JDBC-like) type
|
||||
* when given the native db type.
|
||||
* @param string $nativeType DB native type (e.g. 'TEXT', 'byetea', etc.).
|
||||
* @return int Creole native type (e.g. CreoleTypes::LONGVARCHAR, CreoleTypes::BINARY, etc.).
|
||||
*/
|
||||
public static function getType($nativeType)
|
||||
{
|
||||
if (!self::$typeMap)
|
||||
self::loadTypeMap();
|
||||
|
||||
$t = strtoupper($nativeType);
|
||||
|
||||
if (isset(self::$typeMap[$t])) {
|
||||
return self::$typeMap[$t];
|
||||
} else {
|
||||
return CreoleTypes::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return a native type that corresponds to the specified
|
||||
* Creole (JDBC-like) type.
|
||||
* If there is more than one matching native type, then the LAST defined
|
||||
* native type will be returned.
|
||||
* @param int $creoleType
|
||||
* @return string Native type string.
|
||||
*/
|
||||
public static function getNativeType($creoleType)
|
||||
{
|
||||
if (!self::$typeMap)
|
||||
self::loadTypeMap();
|
||||
|
||||
if (self::$reverseMap === null) {
|
||||
self::$reverseMap = array_flip(self::$typeMap);
|
||||
}
|
||||
return @self::$reverseMap[$creoleType];
|
||||
}
|
||||
|
||||
}
|
90
lib/symfony/vendor/creole/drivers/odbc/README
vendored
Executable file
90
lib/symfony/vendor/creole/drivers/odbc/README
vendored
Executable file
@ -0,0 +1,90 @@
|
||||
|
||||
|
||||
Creole ODBC Bridge Driver
|
||||
=========================
|
||||
|
||||
|
||||
I. Overview
|
||||
-----------
|
||||
|
||||
In the text below, the word "driver" can get somewhat muddled since there are
|
||||
two libraries concerned here (Creole & ODBC). So, we'll use the term "bridge
|
||||
driver" to refer to Creole's ODBC bridge driver, and "ODBC driver" to refer to
|
||||
an ODBC database driver.
|
||||
|
||||
The Creole ODBC Bridge driver provides a solution for databases which
|
||||
currently have no PHP-native interface. It is currently in an experimental
|
||||
stage of development. It has been tested with two ODBC drivers (Sequiter's
|
||||
CodeBase ODBC driver and the MySQL ODBC driver (as a baseline test)). To
|
||||
use any other ODBC drivers you may need to write your own ODBCAdapter-derived
|
||||
class (see below).
|
||||
|
||||
|
||||
II. ODBCAdapter
|
||||
---------------
|
||||
|
||||
Because ODBC itself is a database abstraction library, the bridge driver needed
|
||||
a way of hiding ODBC driver-specific behavior. The solution to this was to
|
||||
create an adapter layer (akin to how the Propel runtime engine works). Think of
|
||||
it as a sub-driver for the bridge driver. Any ODBC driver-specific behavior is
|
||||
handled by an ODBCAdapter-derived class. To use a specific adapter class, you
|
||||
specify its name via a parameter in the connection string:
|
||||
|
||||
odbc://localhost/DSN=CodeBase;?adapter=CodeBase
|
||||
|
||||
The string above will load the following file as the adapter to use with the
|
||||
bridge driver: creole/drivers/odbc/adapters/CodeBaseAdapter.php
|
||||
|
||||
Some ODBC drivers are limited in support for various Creole features. The
|
||||
ODBCAdapter also provides a method for emulation of some of these missing
|
||||
features:
|
||||
|
||||
-The emulatePrepareStmt() method provides a switch for enabling prepared
|
||||
statement emulation for drivers that do not support (or have trouble with)
|
||||
prepared statements. This emulation is disabled by default.
|
||||
|
||||
-The hasLimitOffset() method provides a switch for enabling LIMIT/OFFSET
|
||||
emulation for drivers that do not support this. This emulation is enabled
|
||||
by default. The LIMIT/OFFSET emulation was borrowed from the MSSQL Creole
|
||||
driver.
|
||||
|
||||
-The createResultSet() method provides a switch for enabling cached
|
||||
result sets. To enable this feature, return an instance of
|
||||
ODBCCachedResultSet in the createResultSet() method of your ODBCAdapter-
|
||||
derived class. This can be useful as a workaround for ODBC drivers which
|
||||
lack support for record count retrieval, reverse/absolute cursor
|
||||
scrolling, etc. In most cases, result rows are cached on-demand. So if
|
||||
you only read the first couple rows of a result, then only those rows will
|
||||
be cached.
|
||||
|
||||
-The getIdGenerator() method provides a switch for enabling sequence
|
||||
emulation. This feature is enabled by default in ODBCAdapter and is
|
||||
implemented in the ODBCIdGenerator class. The emulation code was inspired
|
||||
by the PEAR::DB nextID() method. If your database supports sequences or
|
||||
autoincrement natively, you can return your own IdGenerator-derived class
|
||||
instead. Check out some of the other Creole drivers for IdGenerator
|
||||
examples.
|
||||
|
||||
|
||||
III. Incomplete Features
|
||||
------------------------
|
||||
|
||||
-The database metadata classes are not fully tested/complete. Specifically,
|
||||
the ODBCDatabaseInfo class does not currently set the database name. There
|
||||
may be other problems as well.
|
||||
|
||||
-The Creole CallableStatement class (stored procedures) is not currently
|
||||
implemented. No immediate plans to do this in the future, but it looks
|
||||
feasible.
|
||||
|
||||
|
||||
IV. Known Issues
|
||||
----------------
|
||||
|
||||
This driver was developed using the PHP v5.0 final build. During the course
|
||||
of testing I uncovered several bugs in the php_odbc module. I submitted
|
||||
patches for these bugs, but have not yet received word that they were
|
||||
committed (they were just submitted this morning). If you want more details
|
||||
on the problems I encountered or would like a copy of the patches, please
|
||||
e-mail me (dlawson@masterytech.com).
|
||||
|
73
lib/symfony/vendor/creole/drivers/odbc/adapters/CodeBaseAdapter.php
vendored
Executable file
73
lib/symfony/vendor/creole/drivers/odbc/adapters/CodeBaseAdapter.php
vendored
Executable file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: CodeBaseAdapter.php,v 1.3 2005/10/17 19:03:51 dlawson_mi Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/odbc/adapters/ODBCAdapter.php';
|
||||
|
||||
/**
|
||||
* CodeBase driver-specific behavior.
|
||||
*
|
||||
* This adapter is for Sequiter's CodeBaseSQL product. It is a dBase ODBC
|
||||
* driver. The driver only supports forward-only cursor scrolling so this
|
||||
* adapter causes the ODBCCachedResultSet to be used.
|
||||
*
|
||||
* A couple other quirks exist:
|
||||
*
|
||||
* 1) Cannot get blobs to work correctly. If I try writing one to a
|
||||
* LONGVARBINARY typed field, only the first few bytes are written.
|
||||
* This will cause the ResultSetTest::testGetBlob() test case to fail
|
||||
* when running tests for the driver.
|
||||
*
|
||||
* 2) For some reason the character count is off for the
|
||||
* ResultSetTest::testSetClob() test case _only_ when running from the
|
||||
* command line. If I run the same test through a web server it works fine.
|
||||
* Looks like it has something to do with line endings in Windows. The
|
||||
* difference in file sizes is 9803 vs 10090.
|
||||
*
|
||||
* 3) Setting a clob field to null writes a space to the field in the table.
|
||||
* This causes the PreparedStatementTest::testSetNull() test case to fail
|
||||
* when running tests for the driver.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class CodeBaseAdapter extends ODBCAdapter
|
||||
{
|
||||
/**
|
||||
* @see ODBCAdapter::createResultSet()
|
||||
*/
|
||||
public function preservesColumnCase()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCAdapter::createResultSet()
|
||||
*/
|
||||
public function createResultSet($conn, $odbcresult, $fetchmode)
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCResultSet.php';
|
||||
return new ODBCResultSet($conn, $odbcresult, $fetchmode, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
78
lib/symfony/vendor/creole/drivers/odbc/adapters/MySQLAdapter.php
vendored
Executable file
78
lib/symfony/vendor/creole/drivers/odbc/adapters/MySQLAdapter.php
vendored
Executable file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: MySQLAdapter.php,v 1.1 2004/07/27 23:08:30 hlellelid Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/drivers/odbc/ODBCCachedResultSet.php';
|
||||
require_once 'creole/drivers/odbc/ODBCResultSet.php';
|
||||
require_once 'creole/drivers/odbc/adapters/ODBCAdapter.php';
|
||||
|
||||
/**
|
||||
* Implements MySQL driver-specific behavior.
|
||||
*
|
||||
* Obviously it would be much more efficient to simply use the Creole
|
||||
* MySQL driver. This adapter was created for the sole purpose of testing
|
||||
* the ODBC driver.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class MySQLAdapter extends ODBCAdapter
|
||||
{
|
||||
/**
|
||||
* @see ODBCAdapter::hasLimitOffset()
|
||||
*/
|
||||
public function hasLimitOffset()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCAdapter::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT " . ($offset > 0 ? $offset . ", " : "") . $limit;
|
||||
} else if ( $offset > 0 ) {
|
||||
$sql .= " LIMIT " . $offset . ", 18446744073709551615";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCAdapter::escape()
|
||||
*/
|
||||
public function escape($str)
|
||||
{
|
||||
return addslashes($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ODBCAdapter::createResultSet()
|
||||
*/
|
||||
public function createResultSet($conn, $odbcresult, $fetchmode)
|
||||
{
|
||||
// return new ODBCCachedResultSet($conn, $odbcresult, $fetchmode, true);
|
||||
return new ODBCResultSet($conn, $odbcresult, $fetchmode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
115
lib/symfony/vendor/creole/drivers/odbc/adapters/ODBCAdapter.php
vendored
Executable file
115
lib/symfony/vendor/creole/drivers/odbc/adapters/ODBCAdapter.php
vendored
Executable file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCAdapter.php,v 1.3 2005/10/17 19:03:51 dlawson_mi Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default class for ODBC driver-specific behavior.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package creole.drivers.odbc
|
||||
*/
|
||||
class ODBCAdapter
|
||||
{
|
||||
/**
|
||||
* Returns true if column case is preserved in the database when a table
|
||||
* is first created. Returns false if table does not preserve case (i.e.
|
||||
* ProductID => PRODUCTID).
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function preservesColumnCase()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if prepared statements should be emulated. This
|
||||
* might be useful if your driver does not support (or has trouble with)
|
||||
* prepared statements.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function emulatePrepareStmt()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if ODBC driver supports LIMIT/OFFSET via SQL.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasLimitOffset()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PreparedStatementCommon::escape()
|
||||
*/
|
||||
public function escape($str)
|
||||
{
|
||||
// use this instead of magic_quotes_sybase + addslashes(),
|
||||
// just in case multiple RDBMS being used at the same time
|
||||
return str_replace("'", "''", $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the default resultset.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function createResultSet($conn, $odbcresult, $fetchmode)
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCResultSet.php';
|
||||
return new ODBCResultSet($conn, $odbcresult, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default ODBCIdGenerator for emulating sequences.
|
||||
*
|
||||
* @return ODBCIdGenerator
|
||||
*/
|
||||
public function getIdGenerator($conn)
|
||||
{
|
||||
require_once 'creole/drivers/odbc/ODBCIdGenerator.php';
|
||||
return new ODBCIdGenerator($conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if driver support transactions.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function supportsTransactions()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
66
lib/symfony/vendor/creole/drivers/odbc/metadata/ODBCDatabaseInfo.php
vendored
Executable file
66
lib/symfony/vendor/creole/drivers/odbc/metadata/ODBCDatabaseInfo.php
vendored
Executable file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCDatabaseInfo.php,v 1.2 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/DatabaseInfo.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of DatabaseInfo.
|
||||
*
|
||||
* @todo Still need a way to obtain the database name. Not sure how to do this yet.
|
||||
* @todo This might need to be an {@link ODBCAdapter} method.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc.metadata
|
||||
*/
|
||||
class ODBCDatabaseInfo extends DatabaseInfo {
|
||||
|
||||
/**
|
||||
* @see DatabaseInfo::initTables()
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/odbc/metadata/ODBCTableInfo.php';
|
||||
|
||||
$result = @odbc_tables($this->conn->getResource());
|
||||
|
||||
if (!$result)
|
||||
throw new SQLException('Could not list tables', $this->conn->nativeError());
|
||||
|
||||
while (odbc_fetch_row($result))
|
||||
{
|
||||
$tablename = strtoupper(odbc_result($result, 'TABLE_NAME'));
|
||||
$this->tables[$tablename] = new ODBCTableInfo($this, $tablename);
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
// Not sure how this is used yet.
|
||||
}
|
||||
|
||||
}
|
141
lib/symfony/vendor/creole/drivers/odbc/metadata/ODBCTableInfo.php
vendored
Executable file
141
lib/symfony/vendor/creole/drivers/odbc/metadata/ODBCTableInfo.php
vendored
Executable file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: ODBCTableInfo.php,v 1.2 2006/01/17 19:44:39 hlellelid Exp $
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information please see
|
||||
* <http://creole.phpdb.org>.
|
||||
*/
|
||||
|
||||
require_once 'creole/metadata/TableInfo.php';
|
||||
|
||||
/**
|
||||
* ODBC implementation of TableInfo.
|
||||
*
|
||||
* @author Dave Lawson <dlawson@masterytech.com>
|
||||
* @version $Revision: 1.2 $
|
||||
* @package creole.drivers.odbc.metadata
|
||||
*/
|
||||
class ODBCTableInfo extends TableInfo {
|
||||
|
||||
/**
|
||||
* @see TableInfo::initColumns()
|
||||
*/
|
||||
protected function initColumns()
|
||||
{
|
||||
include_once 'creole/metadata/ColumnInfo.php';
|
||||
include_once 'creole/drivers/odbc/ODBCTypes.php';
|
||||
|
||||
ODBCTypes::loadTypeMap($this->conn);
|
||||
|
||||
$result = @odbc_columns($this->conn->getResource(), $this->dbname, '', $this->name);
|
||||
|
||||
if (!$result)
|
||||
throw new SQLException('Could not get column names', $this->conn->nativeError());
|
||||
|
||||
while (odbc_fetch_row($result))
|
||||
{
|
||||
$name = odbc_result($result, 'COLUMN_NAME');
|
||||
$type = odbc_result($result, 'TYPE_NAME');
|
||||
$length = odbc_result($result, 'LENGTH');
|
||||
$is_nullable = odbc_result($result, 'NULLABLE');
|
||||
$default = '';
|
||||
$precision = odbc_result($result, 'PRECISION');
|
||||
$scale = odbc_result($result, 'SCALE');
|
||||
$this->columns[$name] = new ColumnInfo($this, $name, ODBCTypes::getType($type), $type, $length, $precision, $scale, $is_nullable, $default);
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
|
||||
$this->colsLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TableInfo::initPrimaryKey()
|
||||
*/
|
||||
protected function initPrimaryKey()
|
||||
{
|
||||
include_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
$result = @odbc_primarykeys($this->conn->getResource(), $this->dbname, '', $this->name);
|
||||
|
||||
while (odbc_fetch_row($result))
|
||||
{
|
||||
$name = odbc_result($result, 'COLUMN_NAME');
|
||||
|
||||
if (!isset($this->primaryKey))
|
||||
$this->primaryKey = new PrimaryKeyInfo($name);
|
||||
|
||||
$this->primaryKey->addColumn($this->columns[$name]);
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TableInfo::initIndexes()
|
||||
*/
|
||||
protected function initIndexes()
|
||||
{
|
||||
// Not sure if this can be implemented in a driver-independent way.
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TableInfo::initForeignKeys()
|
||||
*/
|
||||
protected function initForeignKeys()
|
||||
{
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
$result = @odbc_foreignkeys($this->conn->getResource(), '', '', '', $this->dbname, '', $this->name);
|
||||
|
||||
while (odbc_fetch_row($result))
|
||||
{
|
||||
$name = odbc_result($result, 'COLUMN_NAME');
|
||||
$ftbl = odbc_result($result, 'FKTABLE_NAME');
|
||||
$fcol = odbc_result($result, 'FKCOLUMN_NAME');
|
||||
|
||||
if (!isset($this->foreignKeys[$name]))
|
||||
{
|
||||
$this->foreignKeys[$name] = new ForeignKeyInfo($name);
|
||||
|
||||
if (($foreignTable = $this->database->getTable($ftbl)) === null)
|
||||
{
|
||||
$foreignTable = new TableInfo($ltbl);
|
||||
$this->database->addTable($foreignTable);
|
||||
}
|
||||
|
||||
if (($foreignCol = $foreignTable->getColumn($name)) === null)
|
||||
{
|
||||
$foreignCol = new ColumnInfo($foreignTable, $name);
|
||||
$foreignTable->addColumn($foreignCol);
|
||||
}
|
||||
|
||||
$this->foreignKeys[$name]->addReference($this->columns[$name], $foreignCol);
|
||||
}
|
||||
}
|
||||
|
||||
@odbc_free_result($result);
|
||||
|
||||
$this->fksLoaded = true;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user