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:
260
lib/symfony/vendor/creole/drivers/pgsql/PgSQLConnection.php
vendored
Executable file
260
lib/symfony/vendor/creole/drivers/pgsql/PgSQLConnection.php
vendored
Executable file
@ -0,0 +1,260 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLConnection.php,v 1.21 2005/08/03 17:56:22 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';
|
||||
include_once 'creole/drivers/pgsql/PgSQLResultSet.php';
|
||||
|
||||
/**
|
||||
* PgSQL implementation of Connection.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org> (Creole)
|
||||
* @author Stig Bakken <ssb@fast.no> (PEAR::DB)
|
||||
* @author Lukas Smith (PEAR::MDB)
|
||||
* @version $Revision: 1.21 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLConnection extends ConnectionCommon implements Connection {
|
||||
|
||||
/**
|
||||
* Affected Rows of last executed query.
|
||||
* Postgres needs this for getUpdateCount()
|
||||
* We used to store the entire result set
|
||||
* instead but that can be a large dataset.
|
||||
* @var int
|
||||
*/
|
||||
private $result_affected_rows;
|
||||
|
||||
/**
|
||||
* Connect to a database and log in as the specified user.
|
||||
*
|
||||
* @param array $dsn The datasource hash.
|
||||
* @param $flags Any connection flags.
|
||||
* @access public
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
function connect($dsninfo, $flags = 0)
|
||||
{
|
||||
global $php_errormsg;
|
||||
|
||||
if (!extension_loaded('pgsql')) {
|
||||
throw new SQLException('pgsql extension not loaded');
|
||||
}
|
||||
|
||||
$this->dsn = $dsninfo;
|
||||
$this->flags = $flags;
|
||||
|
||||
$persistent = ($flags & Creole::PERSISTENT === Creole::PERSISTENT);
|
||||
|
||||
$protocol = (isset($dsninfo['protocol'])) ? $dsninfo['protocol'] : 'tcp';
|
||||
$connstr = '';
|
||||
|
||||
if ($protocol == 'tcp') {
|
||||
if (!empty($dsninfo['hostspec'])) {
|
||||
$connstr = 'host=' . $dsninfo['hostspec'];
|
||||
}
|
||||
if (!empty($dsninfo['port'])) {
|
||||
$connstr .= ' port=' . $dsninfo['port'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($dsninfo['database'])) {
|
||||
$connstr .= ' dbname=\'' . addslashes($dsninfo['database']) . '\'';
|
||||
}
|
||||
if (!empty($dsninfo['username'])) {
|
||||
$connstr .= ' user=\'' . addslashes($dsninfo['username']) . '\'';
|
||||
}
|
||||
if (!empty($dsninfo['password'])) {
|
||||
$connstr .= ' password=\'' . addslashes($dsninfo['password']) . '\'';
|
||||
}
|
||||
if (!empty($dsninfo['options'])) {
|
||||
$connstr .= ' options=' . $dsninfo['options'];
|
||||
}
|
||||
if (!empty($dsninfo['tty'])) {
|
||||
$connstr .= ' tty=' . $dsninfo['tty'];
|
||||
}
|
||||
|
||||
if ($persistent) {
|
||||
$conn = @pg_pconnect($connstr);
|
||||
} else {
|
||||
$conn = @pg_connect($connstr);
|
||||
}
|
||||
|
||||
if (!$conn) {
|
||||
// hide the password from connstr
|
||||
$cleanconnstr = preg_replace('/password=\'.*?\'($|\s)/', 'password=\'*********\'', $connstr);
|
||||
throw new SQLException('Could not connect', $php_errormsg, $cleanconnstr);
|
||||
}
|
||||
|
||||
$this->dblink = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::applyLimit()
|
||||
*/
|
||||
public function applyLimit(&$sql, $offset, $limit)
|
||||
{
|
||||
if ( $limit > 0 ) {
|
||||
$sql .= " LIMIT ".$limit;
|
||||
}
|
||||
if ( $offset > 0 ) {
|
||||
$sql .= " OFFSET ".$offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::disconnect()
|
||||
*/
|
||||
function close()
|
||||
{
|
||||
$ret = @pg_close($this->dblink);
|
||||
$this->result_affected_rows = null;
|
||||
$this->dblink = null;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::simpleQuery()
|
||||
*/
|
||||
function executeQuery($sql, $fetchmode = null)
|
||||
{
|
||||
$result = @pg_query($this->dblink, $sql);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute query', pg_last_error($this->dblink), $sql);
|
||||
}
|
||||
$this->result_affected_rows = (int) @pg_affected_rows($result);
|
||||
|
||||
return new PgSQLResultSet($this, $result, $fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::simpleUpdate()
|
||||
*/
|
||||
function executeUpdate($sql)
|
||||
{
|
||||
$result = @pg_query($this->dblink, $sql);
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not execute update', pg_last_error($this->dblink), $sql);
|
||||
}
|
||||
$this->result_affected_rows = (int) @pg_affected_rows($result);
|
||||
|
||||
return $this->result_affected_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a database transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function beginTrans()
|
||||
{
|
||||
$result = @pg_query($this->dblink, "BEGIN");
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not begin transaction', pg_last_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function commitTrans()
|
||||
{
|
||||
$result = @pg_query($this->dblink, "COMMIT");
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not commit transaction', pg_last_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll back (undo) the current transaction.
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function rollbackTrans()
|
||||
{
|
||||
$result = @pg_query($this->dblink, "ROLLBACK");
|
||||
if (!$result) {
|
||||
throw new SQLException('Could not rollback transaction', pg_last_error($this->dblink));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows affected by the data manipulation
|
||||
* query.
|
||||
* @see Statement::getUpdateCount()
|
||||
* @return int Number of rows affected by the last query.
|
||||
*/
|
||||
function getUpdateCount()
|
||||
{
|
||||
if ( $this->result_affected_rows === null ) {
|
||||
throw new SQLException('getUpdateCount called before any sql queries were executed');
|
||||
}
|
||||
return $this->result_affected_rows;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see Connection::getDatabaseInfo()
|
||||
*/
|
||||
public function getDatabaseInfo()
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php';
|
||||
return new PgSQLDatabaseInfo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::getIdGenerator()
|
||||
*/
|
||||
public function getIdGenerator()
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/PgSQLIdGenerator.php';
|
||||
return new PgSQLIdGenerator($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareStatement()
|
||||
*/
|
||||
public function prepareStatement($sql)
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/PgSQLPreparedStatement.php';
|
||||
return new PgSQLPreparedStatement($this, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::prepareCall()
|
||||
*/
|
||||
public function prepareCall($sql) {
|
||||
throw new SQLException('PostgreSQL does not support stored procedures.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Connection::createStatement()
|
||||
*/
|
||||
public function createStatement()
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/PgSQLStatement.php';
|
||||
return new PgSQLStatement($this);
|
||||
}
|
||||
|
||||
}
|
84
lib/symfony/vendor/creole/drivers/pgsql/PgSQLIdGenerator.php
vendored
Executable file
84
lib/symfony/vendor/creole/drivers/pgsql/PgSQLIdGenerator.php
vendored
Executable file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLIdGenerator.php,v 1.5 2004/03/19 14:19:50 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/IdGenerator.php';
|
||||
|
||||
/**
|
||||
* PostgreSQL IdGenerator implemenation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.5 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLIdGenerator 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($name = null)
|
||||
{
|
||||
if ($name === null) {
|
||||
throw new SQLException("You must specify the sequence name when calling getId() method.");
|
||||
}
|
||||
$rs = $this->conn->executeQuery("SELECT nextval('" . pg_escape_string ( $name ) . "')", ResultSet::FETCHMODE_NUM);
|
||||
$rs->next();
|
||||
return $rs->getInt(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
157
lib/symfony/vendor/creole/drivers/pgsql/PgSQLPreparedStatement.php
vendored
Executable file
157
lib/symfony/vendor/creole/drivers/pgsql/PgSQLPreparedStatement.php
vendored
Executable file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLPreparedStatement.php,v 1.14 2005/04/16 18:55:28 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/PreparedStatement.php';
|
||||
require_once 'creole/common/PreparedStatementCommon.php';
|
||||
|
||||
/**
|
||||
* PgSQL subclass for prepared statements.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.14 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLPreparedStatement extends PreparedStatementCommon implements PreparedStatement {
|
||||
|
||||
/**
|
||||
* Quotes string using native pgsql function (pg_escape_string).
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
protected function escape($str)
|
||||
{
|
||||
return pg_escape_string($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive function to turn multi-dim array into str representation.
|
||||
* @param array $arr
|
||||
* @return string Array in pgsql-friendly string notation: {val1, val2} or {{sub1,sub2}, {sub3, sub4}}
|
||||
*/
|
||||
private function arrayToStr($arr)
|
||||
{
|
||||
$parts = array();
|
||||
foreach((array)$arr as $el) {
|
||||
if (is_array($el)) {
|
||||
$parts[] = $this->arrayToStr($el);
|
||||
} else {
|
||||
if (is_string($el)) {
|
||||
$parts[] = '"' . $this->escape($el) . '"';
|
||||
} else {
|
||||
$parts[] = $el;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '{' . implode(',', $parts) . '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array.
|
||||
* Unless a driver-specific method is used, this means simply serializing
|
||||
* the passed parameter and storing it as a string.
|
||||
* @param int $paramIndex
|
||||
* @param array $value
|
||||
* @return void
|
||||
* @see PreparedStatement::setArray()
|
||||
*/
|
||||
function setArray($paramIndex, $value)
|
||||
{
|
||||
if( $paramIndex > $this->positionsCount || $paramIndex < 1) {
|
||||
throw new SQLException('Cannot bind to invalid param index: '.$paramIndex);
|
||||
}
|
||||
if ($value === null)
|
||||
$this->setNull($paramIndex);
|
||||
else
|
||||
$this->boundInVars[$paramIndex] = "'" . $this->arrayToStr($value) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* For setting value of Postgres BOOLEAN column.
|
||||
* @param int $paramIndex
|
||||
* @param boolean $value
|
||||
* @return void
|
||||
*/
|
||||
function setBoolean($paramIndex, $value)
|
||||
{
|
||||
if( $paramIndex > $this->positionsCount || $paramIndex < 1) {
|
||||
throw new SQLException('Cannot bind to invalid param index: '.$paramIndex);
|
||||
}
|
||||
if ($value === null)
|
||||
$this->setNull($paramIndex);
|
||||
else
|
||||
$this->boundInVars[$paramIndex] = ($value ? "'t'" : "'f'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies sqlite_udf_encode_binary() to ensure that binary contents will be handled correctly by sqlite.
|
||||
* @param int $paramIndex
|
||||
* @param mixed $blob Blob object or string containing data.
|
||||
* @return void
|
||||
*/
|
||||
function setBlob($paramIndex, $blob)
|
||||
{
|
||||
if ($blob === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
// they took magic __toString() out of PHP5.0.0; this sucks
|
||||
if (is_object($blob)) {
|
||||
$blob = $blob->__toString();
|
||||
}
|
||||
$this->boundInVars[$paramIndex] = "'" . pg_escape_bytea( $blob ) . "'";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setTime($paramIndex, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if ( is_numeric ( $value ) ) {
|
||||
$value = date ( "H:i:s O", $value );
|
||||
} elseif ( is_object ( $value ) ) {
|
||||
$value = date ( "H:i:s O", $value->getTime ( ) );
|
||||
}
|
||||
$this->boundInVars [ $paramIndex ] = "'" . $this->escape ( $value ) . "'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $paramIndex
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
function setTimestamp($paramIndex, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
$this->setNull($paramIndex);
|
||||
} else {
|
||||
if (is_numeric($value)) $value = date('Y-m-d H:i:s O', $value);
|
||||
elseif (is_object($value)) $value = date("Y-m-d H:i:s O", $value->getTime());
|
||||
$this->boundInVars[$paramIndex] = "'".$this->escape($value)."'";
|
||||
}
|
||||
}
|
||||
}
|
205
lib/symfony/vendor/creole/drivers/pgsql/PgSQLResultSet.php
vendored
Executable file
205
lib/symfony/vendor/creole/drivers/pgsql/PgSQLResultSet.php
vendored
Executable file
@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLResultSet.php,v 1.31 2006/01/17 19:44:40 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';
|
||||
|
||||
/**
|
||||
* PostgreSQL implementation of ResultSet.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.31 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLResultSet extends ResultSetCommon implements ResultSet {
|
||||
|
||||
|
||||
/**
|
||||
* Gets optimized PgSQLResultSetIterator.
|
||||
* @return PgSQLResultSetIterator
|
||||
*/
|
||||
/*
|
||||
public function getIterator()
|
||||
{
|
||||
require_once 'creole/drivers/pgsql/PgSQLResultSetIterator.php';
|
||||
return new PgSQLResultSetIterator($this);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Postgres doesn't actually move the db pointer. The specific row
|
||||
* is fetched by call to pg_fetch_array() rather than by a seek and
|
||||
* then an unspecified pg_fetch_array() call.
|
||||
*
|
||||
* The only side-effect of this situation is that we don't really know
|
||||
* if the seek will fail or succeed until we have called next(). This
|
||||
* behavior is acceptible - and explicitly documented in
|
||||
* ResultSet::seek() phpdoc.
|
||||
*
|
||||
* @see ResultSet::seek()
|
||||
*/
|
||||
public function seek($rownum)
|
||||
{
|
||||
if ($rownum < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PostgreSQL rows start w/ 0, but this works, because we are
|
||||
// looking to move the position _before_ the next desired position
|
||||
$this->cursorPos = $rownum;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
|
||||
$this->fields = @pg_fetch_array($this->result, $this->cursorPos, $this->fetchmode);
|
||||
|
||||
if (!$this->fields) {
|
||||
$err = @pg_result_error($this->result);
|
||||
if (!$err) {
|
||||
// We've advanced beyond end of recordset.
|
||||
$this->afterLast();
|
||||
return false;
|
||||
} else {
|
||||
throw new SQLException("Error fetching result", $err);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->fetchmode === ResultSet::FETCHMODE_ASSOC && $this->lowerAssocCase) {
|
||||
$this->fields = array_change_key_case($this->fields, CASE_LOWER);
|
||||
}
|
||||
// Advance cursor position
|
||||
$this->cursorPos++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::getRecordCount()
|
||||
*/
|
||||
public function getRecordCount()
|
||||
{
|
||||
$rows = @pg_num_rows($this->result);
|
||||
if ($rows === null) {
|
||||
throw new SQLException("Error fetching num rows", pg_result_error($this->result));
|
||||
}
|
||||
return (int) $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ResultSet::close()
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->fields = array();
|
||||
@pg_free_result($this->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Postgres string representation of array into native PHP array.
|
||||
* @param string $str Postgres string array rep: {1223, 2343} or {{"welcome", "home"}, {"test2", ""}}
|
||||
* @return array
|
||||
*/
|
||||
private function strToArray($str)
|
||||
{
|
||||
$str = substr($str, 1, -1); // remove { }
|
||||
$res = array();
|
||||
|
||||
$subarr = array();
|
||||
$in_subarr = 0;
|
||||
|
||||
$toks = explode(',', $str);
|
||||
foreach($toks as $tok) {
|
||||
if ($in_subarr > 0) { // already in sub-array?
|
||||
$subarr[$in_subarr][] = $tok;
|
||||
if ('}' === substr($tok, -1, 1)) { // check to see if we just added last component
|
||||
$res[] = $this->strToArray(implode(',', $subarr[$in_subarr]));
|
||||
$in_subarr--;
|
||||
}
|
||||
} elseif ($tok{0} === '{') { // we're inside a new sub-array
|
||||
if ('}' !== substr($tok, -1, 1)) {
|
||||
$in_subarr++;
|
||||
// if sub-array has more than one element
|
||||
$subarr[$in_subarr] = array();
|
||||
$subarr[$in_subarr][] = $tok;
|
||||
} else {
|
||||
$res[] = $this->strToArray($tok);
|
||||
}
|
||||
} else { // not sub-array
|
||||
$val = trim($tok, '"'); // remove " (surrounding strings)
|
||||
// perform type castng here?
|
||||
$res[] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a column as an array.
|
||||
* The value of the column is unserialized & returned as an array.
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1.
|
||||
* @return array
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getArray($column)
|
||||
{
|
||||
if (is_int($column)) { $column--; } // because Java convention is to start at 1
|
||||
if (!array_key_exists($column, $this->fields)) { throw new SQLException("Invalid resultset column: " . (is_int($column) ? $column + 1 : $column)); }
|
||||
if ($this->fields[$column] === null) { return null; }
|
||||
return $this->strToArray($this->fields[$column]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Blob with contents of column value.
|
||||
*
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1 (if ResultSet::FETCHMODE_NUM was used).
|
||||
* @return Blob New Blob with data from column.
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getBlob($column)
|
||||
{
|
||||
if (is_int($column)) { $column--; } // because Java convention is to start at 1
|
||||
if (!array_key_exists($column, $this->fields)) { throw new SQLException("Invalid resultset column: " . (is_int($column) ? $column + 1 : $column)); }
|
||||
if ($this->fields[$column] === null) { return null; }
|
||||
require_once 'creole/util/Blob.php';
|
||||
$b = new Blob();
|
||||
$b->setContents(pg_unescape_bytea($this->fields[$column]));
|
||||
return $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $column Column name (string) or index (int) starting with 1.
|
||||
* @return boolean
|
||||
* @throws SQLException - If the column specified is not a valid key in current field array.
|
||||
*/
|
||||
public function getBoolean($column)
|
||||
{
|
||||
if (is_int($column)) { $column--; } // because Java convention is to start at 1
|
||||
if (!array_key_exists($column, $this->fields)) { throw new SQLException("Invalid resultset column: " . (is_int($column) ? $column + 1 : $column)); }
|
||||
if ($this->fields[$column] === null) { return null; }
|
||||
return ($this->fields[$column] === 't');
|
||||
}
|
||||
|
||||
}
|
109
lib/symfony/vendor/creole/drivers/pgsql/PgSQLResultSetIterator.php
vendored
Executable file
109
lib/symfony/vendor/creole/drivers/pgsql/PgSQLResultSetIterator.php
vendored
Executable file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLResultSetIterator.php,v 1.1 2004/12/04 05:58:53 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>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Optimized iterator for PostgreSQL, based off of SQLite iterator.
|
||||
* Testing with SeekableIterator, no idea if it will keep this
|
||||
* functionality or what uses it or even how to use it as yet.
|
||||
*
|
||||
* @author Cameron Brunner <webmaster@animetorrents.com>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLResultSetIterator implements SeekableIterator, Countable {
|
||||
|
||||
private $result;
|
||||
private $pos = 0;
|
||||
private $fetchmode;
|
||||
private $row_count;
|
||||
private $rs;
|
||||
|
||||
/**
|
||||
* Construct the iterator.
|
||||
* @param PgSQLResultSet $rs
|
||||
*/
|
||||
public function __construct(PgSQLResultSet $rs)
|
||||
{
|
||||
$this->result = $rs->getResource();
|
||||
$this->fetchmode = $rs->getFetchmode();
|
||||
$this->row_count = $rs->getRecordCount();
|
||||
$this->rs = $rs; // This is to address reference count bug: http://creole.phpdb.org/trac/ticket/6
|
||||
}
|
||||
|
||||
/**
|
||||
* This method actually has no effect, since we do not rewind ResultSet for iteration.
|
||||
*/
|
||||
function rewind()
|
||||
{
|
||||
$this->pos = 0;
|
||||
}
|
||||
|
||||
function valid()
|
||||
{
|
||||
return ( $this->pos < $this->row_count );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cursor position. Note that this will not necessarily
|
||||
* be 1 for the first row, since no rewind is performed at beginning
|
||||
* of iteration.
|
||||
* @return int
|
||||
*/
|
||||
function key()
|
||||
{
|
||||
return $this->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the row (assoc array) at current cursor pos.
|
||||
* @return array
|
||||
*/
|
||||
function current()
|
||||
{
|
||||
return pg_fetch_array($this->result, $this->pos, $this->fetchmode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances internal cursor pos.
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
$this->pos++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cursor to specific value.
|
||||
*/
|
||||
function seek ( $index )
|
||||
{
|
||||
if ( ! is_int ( $index ) ) {
|
||||
throw new InvalidArgumentException ( 'Invalid arguement to seek' );
|
||||
}
|
||||
if ( $index < 0 || $index > $this->row_count ) {
|
||||
throw new OutOfBoundsException ( 'Invalid seek position' );
|
||||
}
|
||||
$this->pos = $index;
|
||||
}
|
||||
|
||||
function count ( ) {
|
||||
return $this->row_count;
|
||||
}
|
||||
}
|
34
lib/symfony/vendor/creole/drivers/pgsql/PgSQLStatement.php
vendored
Executable file
34
lib/symfony/vendor/creole/drivers/pgsql/PgSQLStatement.php
vendored
Executable file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLStatement.php,v 1.1 2004/02/19 02:49:42 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';
|
||||
|
||||
/**
|
||||
* PostgreSQL Statement implementation.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLStatement extends StatementCommon implements Statement {
|
||||
|
||||
}
|
101
lib/symfony/vendor/creole/drivers/pgsql/PgSQLTypes.php
vendored
Executable file
101
lib/symfony/vendor/creole/drivers/pgsql/PgSQLTypes.php
vendored
Executable file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* $Id: PgSQLTypes.php,v 1.8 2004/04/09 19:16:05 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';
|
||||
|
||||
/**
|
||||
* PostgreSQL types / type map.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.8 $
|
||||
* @package creole.drivers.pgsql
|
||||
*/
|
||||
class PgSQLTypes extends CreoleTypes {
|
||||
|
||||
/** Map PostgreSQL native types to Creole (JDBC) types. */
|
||||
private static $typeMap = array (
|
||||
"int2" => CreoleTypes::SMALLINT,
|
||||
"int4" => CreoleTypes::INTEGER,
|
||||
"oid" => CreoleTypes::INTEGER,
|
||||
"int8" => CreoleTypes::BIGINT,
|
||||
"cash" => CreoleTypes::DOUBLE,
|
||||
"money" => CreoleTypes::DOUBLE,
|
||||
"numeric" => CreoleTypes::NUMERIC,
|
||||
"float4" => CreoleTypes::REAL,
|
||||
"float8" => CreoleTypes::DOUBLE,
|
||||
"bpchar" => CreoleTypes::CHAR,
|
||||
"char" => CreoleTypes::CHAR,
|
||||
"char2" => CreoleTypes::CHAR,
|
||||
"char4" => CreoleTypes::CHAR,
|
||||
"char8" => CreoleTypes::CHAR,
|
||||
"char16" => CreoleTypes::CHAR,
|
||||
"varchar" => CreoleTypes::VARCHAR,
|
||||
"text" => CreoleTypes::VARCHAR,
|
||||
"name" => CreoleTypes::VARCHAR,
|
||||
"filename" => CreoleTypes::VARCHAR,
|
||||
"bytea" => CreoleTypes::BINARY,
|
||||
"bool" => CreoleTypes::BOOLEAN,
|
||||
"date" => CreoleTypes::DATE,
|
||||
"time" => CreoleTypes::TIME,
|
||||
"abstime" => CreoleTypes::TIMESTAMP,
|
||||
"timestamp" => CreoleTypes::TIMESTAMP,
|
||||
"timestamptz" => CreoleTypes::TIMESTAMP,
|
||||
"_bool" => CreoleTypes::ARR,
|
||||
"_char" => CreoleTypes::ARR,
|
||||
"_int2" => CreoleTypes::ARR,
|
||||
"_int4" => CreoleTypes::ARR,
|
||||
"_text" => CreoleTypes::ARR,
|
||||
"_oid" => CreoleTypes::ARR,
|
||||
"_varchar" => CreoleTypes::ARR,
|
||||
"_int8" => CreoleTypes::ARR,
|
||||
"_float4" => CreoleTypes::ARR,
|
||||
"_float8" => CreoleTypes::ARR,
|
||||
"_abstime" => CreoleTypes::ARR,
|
||||
"_date" => CreoleTypes::ARR,
|
||||
"_time" => CreoleTypes::ARR,
|
||||
"_timestamp" => CreoleTypes::ARR,
|
||||
"_numeric" => CreoleTypes::ARR,
|
||||
"_bytea" => CreoleTypes::ARR,
|
||||
);
|
||||
|
||||
/** Reverse lookup map, created on demand. */
|
||||
private static $reverseMap = null;
|
||||
|
||||
public static function getType($pgsqlType)
|
||||
{
|
||||
$t = strtolower($pgsqlType);
|
||||
if (isset(self::$typeMap[$t])) {
|
||||
return self::$typeMap[$t];
|
||||
} else {
|
||||
return CreoleTypes::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getNativeType($creoleType)
|
||||
{
|
||||
if (self::$reverseMap === null) {
|
||||
self::$reverseMap = array_flip(self::$typeMap);
|
||||
}
|
||||
return @self::$reverseMap[$creoleType];
|
||||
}
|
||||
|
||||
}
|
115
lib/symfony/vendor/creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php
vendored
Executable file
115
lib/symfony/vendor/creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php
vendored
Executable file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLDatabaseInfo.php,v 1.11 2006/01/17 19:44:40 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';
|
||||
|
||||
/**
|
||||
* MySQL implementation of DatabaseInfo.
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.11 $
|
||||
* @package creole.drivers.pgsql.metadata
|
||||
*/
|
||||
class PgSQLDatabaseInfo extends DatabaseInfo {
|
||||
|
||||
/**
|
||||
* @throws SQLException
|
||||
* @return void
|
||||
*/
|
||||
protected function initTables()
|
||||
{
|
||||
include_once 'creole/drivers/pgsql/metadata/PgSQLTableInfo.php';
|
||||
|
||||
// Get Database Version
|
||||
// TODO: www.php.net/pg_version
|
||||
$result = pg_query ($this->conn->getResource(), "SELECT version() as ver");
|
||||
|
||||
if (!$result)
|
||||
{
|
||||
throw new SQLException ("Failed to select database version");
|
||||
} // if (!$result)
|
||||
$row = pg_fetch_assoc ($result, 0);
|
||||
$arrVersion = sscanf ($row['ver'], '%*s %d.%d');
|
||||
$version = sprintf ("%d.%d", $arrVersion[0], $arrVersion[1]);
|
||||
// Clean up
|
||||
$arrVersion = null;
|
||||
$row = null;
|
||||
pg_free_result ($result);
|
||||
$result = null;
|
||||
|
||||
$result = pg_query($this->conn->getResource(), "SELECT oid, relname FROM pg_class
|
||||
WHERE relkind = 'r' AND relnamespace = (SELECT oid
|
||||
FROM pg_namespace
|
||||
WHERE
|
||||
nspname NOT IN ('information_schema','pg_catalog')
|
||||
AND nspname NOT LIKE 'pg_temp%'
|
||||
AND nspname NOT LIKE 'pg_toast%'
|
||||
LIMIT 1)
|
||||
ORDER BY relname");
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list tables", pg_last_error($this->dblink));
|
||||
}
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
$this->tables[strtoupper($row['relname'])] = new PgSQLTableInfo($this, $row['relname'], $version, $row['oid']);
|
||||
}
|
||||
|
||||
$this->tablesLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* PgSQL sequences.
|
||||
*
|
||||
* @return void
|
||||
* @throws SQLException
|
||||
*/
|
||||
protected function initSequences()
|
||||
{
|
||||
|
||||
$this->sequences = array();
|
||||
|
||||
$result = pg_query($this->conn->getResource(), "SELECT oid, relname FROM pg_class
|
||||
WHERE relkind = 'S' AND relnamespace = (SELECT oid
|
||||
FROM pg_namespace
|
||||
WHERE
|
||||
nspname NOT IN ('information_schema','pg_catalog')
|
||||
AND nspname NOT LIKE 'pg_temp%'
|
||||
AND nspname NOT LIKE 'pg_toast%'
|
||||
LIMIT 1)
|
||||
ORDER BY relname");
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list sequences", pg_last_error($this->dblink));
|
||||
}
|
||||
|
||||
while ($row = pg_fetch_assoc($result)) {
|
||||
// FIXME -- decide what info we need for sequences & then create a SequenceInfo object (if needed)
|
||||
$obj = new stdClass;
|
||||
$obj->name = $row['relname'];
|
||||
$obj->oid = $row['oid'];
|
||||
$this->sequences[strtoupper($row['relname'])] = $obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
423
lib/symfony/vendor/creole/drivers/pgsql/metadata/PgSQLTableInfo.php
vendored
Executable file
423
lib/symfony/vendor/creole/drivers/pgsql/metadata/PgSQLTableInfo.php
vendored
Executable file
@ -0,0 +1,423 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id: PgSQLTableInfo.php,v 1.31 2006/01/17 19:44:40 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';
|
||||
|
||||
/**
|
||||
* PgSQL implementation of TableInfo.
|
||||
*
|
||||
* See this Python code by David M. Cook for some good reference on Pgsql metadata
|
||||
* functions:
|
||||
* @link http://www.sandpyt.org/pipermail/sandpyt/2003-March/000008.html
|
||||
*
|
||||
* Here's some more information from postgresql:
|
||||
* @link http://developer.postgresql.org/docs/pgsql/src/backend/catalog/information_schema.sql
|
||||
*
|
||||
* @todo -c Eventually move to supporting only Postgres >= 7.4, which has the information_schema
|
||||
*
|
||||
* @author Hans Lellelid <hans@xmpl.org>
|
||||
* @version $Revision: 1.31 $
|
||||
* @package creole.drivers.pgsql.metadata
|
||||
*/
|
||||
class PgSQLTableInfo extends TableInfo {
|
||||
|
||||
/**
|
||||
* Database Version.
|
||||
* @var String
|
||||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* Table OID
|
||||
* @var Integer
|
||||
*/
|
||||
private $oid;
|
||||
|
||||
/**
|
||||
* @param string $table The table name.
|
||||
* @param string $database The database name.
|
||||
* @param resource $dblink The db connection resource.
|
||||
*/
|
||||
function __construct(DatabaseInfo $database, $name, $version, $intOID) {
|
||||
parent::__construct ($database, $name);
|
||||
$this->version = $version;
|
||||
$this->oid = $intOID;
|
||||
} // function __construct(DatabaseInfo $database, $name) {
|
||||
|
||||
/** Load the columns for this table */
|
||||
protected function initColumns () {
|
||||
// Include dependencies
|
||||
include_once ('creole/metadata/ColumnInfo.php');
|
||||
include_once ('creole/drivers/pgsql/PgSQLTypes.php');
|
||||
|
||||
// Get the columns, types, etc.
|
||||
// Based on code from pgAdmin3 (http://www.pgadmin.org/)
|
||||
$result = pg_query ($this->conn->getResource(), sprintf ("SELECT
|
||||
att.attname,
|
||||
att.atttypmod,
|
||||
att.atthasdef,
|
||||
att.attnotnull,
|
||||
def.adsrc,
|
||||
CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray,
|
||||
CASE
|
||||
WHEN ty.typname = 'bpchar'
|
||||
THEN 'char'
|
||||
WHEN ty.typname = '_bpchar'
|
||||
THEN '_char'
|
||||
ELSE
|
||||
ty.typname
|
||||
END AS typname,
|
||||
ty.typtype
|
||||
FROM pg_attribute att
|
||||
JOIN pg_type ty ON ty.oid=att.atttypid
|
||||
LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
|
||||
WHERE att.attrelid = %d AND att.attnum > 0
|
||||
AND att.attisdropped IS FALSE
|
||||
ORDER BY att.attnum", $this->oid));
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list fields for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
while($row = pg_fetch_assoc($result)) {
|
||||
|
||||
$size = null;
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
// Check to ensure that this column isn't an array data type
|
||||
if (((int) $row['isarray']) === 1)
|
||||
{
|
||||
throw new SQLException (sprintf ("Array datatypes are not currently supported [%s.%s]", $this->name, $row['attname']));
|
||||
} // if (((int) $row['isarray']) === 1)
|
||||
$name = $row['attname'];
|
||||
// If they type is a domain, Process it
|
||||
if (strtolower ($row['typtype']) == 'd')
|
||||
{
|
||||
$arrDomain = $this->processDomain ($row['typname']);
|
||||
$type = $arrDomain['type'];
|
||||
$size = $arrDomain['length'];
|
||||
$precision = $size;
|
||||
$scale = $arrDomain['scale'];
|
||||
$boolHasDefault = (strlen (trim ($row['atthasdef'])) > 0) ? $row['atthasdef'] : $arrDomain['hasdefault'];
|
||||
$default = (strlen (trim ($row['adsrc'])) > 0) ? $row['adsrc'] : $arrDomain['default'];
|
||||
$is_nullable = (strlen (trim ($row['attnotnull'])) > 0) ? $row['attnotnull'] : $arrDomain['notnull'];
|
||||
$is_nullable = (($is_nullable == 't') ? false : true);
|
||||
} // if (strtolower ($row['typtype']) == 'd')
|
||||
else
|
||||
{
|
||||
$type = $row['typname'];
|
||||
$arrLengthPrecision = $this->processLengthScale ($row['atttypmod'], $type);
|
||||
$size = $arrLengthPrecision['length'];
|
||||
$precision = $size;
|
||||
$scale = $arrLengthPrecision['scale'];
|
||||
$boolHasDefault = $row['atthasdef'];
|
||||
$default = $row['adsrc'];
|
||||
$is_nullable = (($row['attnotnull'] == 't') ? false : true);
|
||||
} // else (strtolower ($row['typtype']) == 'd')
|
||||
|
||||
$autoincrement = null;
|
||||
|
||||
// if column has a default
|
||||
if (($boolHasDefault == 't') && (strlen (trim ($default)) > 0))
|
||||
{
|
||||
if (!preg_match('/^nextval\(/', $default))
|
||||
{
|
||||
$strDefault= preg_replace ('/::[\W\D]*/', '', $default);
|
||||
$default = str_replace ("'", '', $strDefault);
|
||||
} // if (!preg_match('/^nextval\(/', $row['atthasdef']))
|
||||
else
|
||||
{
|
||||
$autoincrement = true;
|
||||
$default = null;
|
||||
} // else
|
||||
} // if (($boolHasDefault == 't') && (strlen (trim ($default)) > 0))
|
||||
else
|
||||
{
|
||||
$default = null;
|
||||
} // else (($boolHasDefault == 't') && (strlen (trim ($default)) > 0))
|
||||
|
||||
$this->columns[$name] = new ColumnInfo($this, $name, PgSQLTypes::getType($type), $type, $size, $precision, $scale, $is_nullable, $default, $autoincrement);
|
||||
}
|
||||
|
||||
$this->colsLoaded = true;
|
||||
} // protected function initColumns ()
|
||||
|
||||
private function processLengthScale ($intTypmod, $strName)
|
||||
{
|
||||
// Define the return array
|
||||
$arrRetVal = array ('length'=>null, 'scale'=>null);
|
||||
|
||||
// Some datatypes don't have a Typmod
|
||||
if ($intTypmod == -1)
|
||||
{
|
||||
return $arrRetVal;
|
||||
} // if ($intTypmod == -1)
|
||||
|
||||
// Numeric Datatype?
|
||||
if ($strName == PgSQLTypes::getNativeType (CreoleTypes::NUMERIC))
|
||||
{
|
||||
$intLen = ($intTypmod - 4) >> 16;
|
||||
$intPrec = ($intTypmod - 4) & 0xffff;
|
||||
$intLen = sprintf ("%ld", $intLen);
|
||||
if ($intPrec)
|
||||
{
|
||||
$intPrec = sprintf ("%ld", $intPrec);
|
||||
} // if ($intPrec)
|
||||
$arrRetVal['length'] = $intLen;
|
||||
$arrRetVal['scale'] = $intPrec;
|
||||
} // if ($strName == PgSQLTypes::getNativeType (CreoleTypes::NUMERIC))
|
||||
elseif ($strName == PgSQLTypes::getNativeType (CreoleTypes::TIME) || $strName == 'timetz'
|
||||
|| $strName == PgSQLTypes::getNativeType (CreoleTypes::TIMESTAMP) || $strName == 'timestamptz'
|
||||
|| $strName == 'interval' || $strName == 'bit')
|
||||
{
|
||||
$arrRetVal['length'] = sprintf ("%ld", $intTypmod);
|
||||
} // elseif (TIME, TIMESTAMP, INTERVAL, BIT)
|
||||
else
|
||||
{
|
||||
$arrRetVal['length'] = sprintf ("%ld", ($intTypmod - 4));
|
||||
} // else
|
||||
return $arrRetVal;
|
||||
} // private function processLengthScale ($intTypmod, $strName)
|
||||
|
||||
private function processDomain ($strDomain)
|
||||
{
|
||||
if (strlen (trim ($strDomain)) < 1)
|
||||
{
|
||||
throw new SQLException ("Invalid domain name [" . $strDomain . "]");
|
||||
} // if (strlen (trim ($strDomain)) < 1)
|
||||
$result = pg_query ($this->conn->getResource(), sprintf ("SELECT
|
||||
d.typname as domname,
|
||||
b.typname as basetype,
|
||||
d.typlen,
|
||||
d.typtypmod,
|
||||
d.typnotnull,
|
||||
d.typdefault
|
||||
FROM pg_type d
|
||||
INNER JOIN pg_type b ON b.oid = CASE WHEN d.typndims > 0 then d.typelem ELSE d.typbasetype END
|
||||
WHERE
|
||||
d.typtype = 'd'
|
||||
AND d.typname = '%s'
|
||||
ORDER BY d.typname", $strDomain));
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Query for domain [" . $strDomain . "] failed.", pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
$row = pg_fetch_assoc ($result);
|
||||
if (!$row)
|
||||
{
|
||||
throw new SQLException ("Domain [" . $strDomain . "] not found.");
|
||||
} // if (!$row)
|
||||
$arrDomain = array ();
|
||||
$arrDomain['type'] = $row['basetype'];
|
||||
$arrLengthPrecision = $this->processLengthScale ($row['typtypmod'], $row['basetype']);
|
||||
$arrDomain['length'] = $arrLengthPrecision['length'];
|
||||
$arrDomain['scale'] = $arrLengthPrecision['scale'];
|
||||
$arrDomain['notnull'] = $row['typnotnull'];
|
||||
$arrDomain['default'] = $row['typdefault'];
|
||||
$arrDomain['hasdefault'] = (strlen (trim ($row['typdefault'])) > 0) ? 't' : 'f';
|
||||
|
||||
pg_free_result ($result);
|
||||
return $arrDomain;
|
||||
} // private function processDomain ($strDomain)
|
||||
|
||||
/** Load foreign keys for this table. */
|
||||
protected function initForeignKeys()
|
||||
{
|
||||
include_once 'creole/metadata/ForeignKeyInfo.php';
|
||||
|
||||
$result = pg_query ($this->conn->getResource(), sprintf ("SELECT
|
||||
conname,
|
||||
confupdtype,
|
||||
confdeltype,
|
||||
cl.relname as fktab,
|
||||
a2.attname as fkcol,
|
||||
cr.relname as reftab,
|
||||
a1.attname as refcol
|
||||
FROM pg_constraint ct
|
||||
JOIN pg_class cl ON cl.oid=conrelid
|
||||
JOIN pg_class cr ON cr.oid=confrelid
|
||||
LEFT JOIN pg_catalog.pg_attribute a1 ON a1.attrelid = ct.confrelid
|
||||
LEFT JOIN pg_catalog.pg_attribute a2 ON a2.attrelid = ct.conrelid
|
||||
WHERE
|
||||
contype='f'
|
||||
AND conrelid = %d
|
||||
AND a2.attnum = ct.conkey[1]
|
||||
AND a1.attnum = ct.confkey[1]
|
||||
ORDER BY conname", $this->oid));
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list foreign keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
while($row = pg_fetch_assoc($result)) {
|
||||
$name = $row['conname'];
|
||||
$local_table = $row['fktab'];
|
||||
$local_column = $row['fkcol'];
|
||||
$foreign_table = $row['reftab'];
|
||||
$foreign_column = $row['refcol'];
|
||||
|
||||
// On Update
|
||||
switch ($row['confupdtype']) {
|
||||
case 'c':
|
||||
$onupdate = ForeignKeyInfo::CASCADE; break;
|
||||
case 'd':
|
||||
$onupdate = ForeignKeyInfo::SETDEFAULT; break;
|
||||
case 'n':
|
||||
$onupdate = ForeignKeyInfo::SETNULL; break;
|
||||
case 'r':
|
||||
$onupdate = ForeignKeyInfo::RESTRICT; break;
|
||||
default:
|
||||
case 'a':
|
||||
//NOACTION is the postgresql default
|
||||
$onupdate = ForeignKeyInfo::NONE; break;
|
||||
}
|
||||
// On Delete
|
||||
switch ($row['confdeltype']) {
|
||||
case 'c':
|
||||
$ondelete = ForeignKeyInfo::CASCADE; break;
|
||||
case 'd':
|
||||
$ondelete = ForeignKeyInfo::SETDEFAULT; break;
|
||||
case 'n':
|
||||
$ondelete = ForeignKeyInfo::SETNULL; break;
|
||||
case 'r':
|
||||
$ondelete = ForeignKeyInfo::RESTRICT; break;
|
||||
default:
|
||||
case 'a':
|
||||
//NOACTION is the postgresql default
|
||||
$ondelete = ForeignKeyInfo::NONE; break;
|
||||
}
|
||||
|
||||
|
||||
$foreignTable = $this->database->getTable($foreign_table);
|
||||
$foreignColumn = $foreignTable->getColumn($foreign_column);
|
||||
|
||||
$localTable = $this->database->getTable($local_table);
|
||||
$localColumn = $localTable->getColumn($local_column);
|
||||
|
||||
if (!isset($this->foreignKeys[$name])) {
|
||||
$this->foreignKeys[$name] = new ForeignKeyInfo($name);
|
||||
}
|
||||
$this->foreignKeys[$name]->addReference($localColumn, $foreignColumn, $ondelete, $onupdate);
|
||||
}
|
||||
|
||||
$this->fksLoaded = true;
|
||||
}
|
||||
|
||||
/** Load indexes for this table */
|
||||
protected function initIndexes()
|
||||
{
|
||||
include_once 'creole/metadata/IndexInfo.php';
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
$result = pg_query ($this->conn->getResource(), sprintf ("SELECT
|
||||
DISTINCT ON(cls.relname)
|
||||
cls.relname as idxname,
|
||||
indkey,
|
||||
indisunique
|
||||
FROM pg_index idx
|
||||
JOIN pg_class cls ON cls.oid=indexrelid
|
||||
WHERE indrelid = %d AND NOT indisprimary
|
||||
ORDER BY cls.relname", $this->oid));
|
||||
|
||||
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
while($row = pg_fetch_assoc($result)) {
|
||||
$name = $row["idxname"];
|
||||
$unique = ($row["indisunique"] == 't') ? true : false;
|
||||
if (!isset($this->indexes[$name])) {
|
||||
$this->indexes[$name] = new IndexInfo($name, $unique);
|
||||
}
|
||||
$arrColumns = explode (' ', $row['indkey']);
|
||||
foreach ($arrColumns as $intColNum)
|
||||
{
|
||||
$result2 = pg_query ($this->conn->getResource(), sprintf ("SELECT a.attname
|
||||
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
|
||||
WHERE c.oid = '%s' AND a.attnum = %d AND NOT a.attisdropped
|
||||
ORDER BY a.attnum", $this->oid, $intColNum));
|
||||
if (!$result2)
|
||||
{
|
||||
throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
$row2 = pg_fetch_assoc($result2);
|
||||
$this->indexes[$name]->addColumn($this->columns[ $row2['attname'] ]);
|
||||
} // foreach ($arrColumns as $intColNum)
|
||||
}
|
||||
|
||||
$this->indexesLoaded = true;
|
||||
}
|
||||
|
||||
/** Loads the primary keys for this table. */
|
||||
protected function initPrimaryKey() {
|
||||
|
||||
include_once 'creole/metadata/PrimaryKeyInfo.php';
|
||||
|
||||
|
||||
// columns have to be loaded first
|
||||
if (!$this->colsLoaded) $this->initColumns();
|
||||
|
||||
// Primary Keys
|
||||
|
||||
$result = pg_query($this->conn->getResource(), sprintf ("SELECT
|
||||
DISTINCT ON(cls.relname)
|
||||
cls.relname as idxname,
|
||||
indkey,
|
||||
indisunique
|
||||
FROM pg_index idx
|
||||
JOIN pg_class cls ON cls.oid=indexrelid
|
||||
WHERE indrelid = %s AND indisprimary
|
||||
ORDER BY cls.relname", $this->oid));
|
||||
if (!$result) {
|
||||
throw new SQLException("Could not list primary keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
|
||||
// Loop through the returned results, grouping the same key_name together
|
||||
// adding each column for that key.
|
||||
|
||||
while($row = pg_fetch_assoc($result)) {
|
||||
$arrColumns = explode (' ', $row['indkey']);
|
||||
foreach ($arrColumns as $intColNum)
|
||||
{
|
||||
$result2 = pg_query ($this->conn->getResource(), sprintf ("SELECT a.attname
|
||||
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
|
||||
WHERE c.oid = '%s' AND a.attnum = %d AND NOT a.attisdropped
|
||||
ORDER BY a.attnum", $this->oid, $intColNum));
|
||||
if (!$result2)
|
||||
{
|
||||
throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource()));
|
||||
}
|
||||
$row2 = pg_fetch_assoc($result2);
|
||||
if (!isset($this->primaryKey)) {
|
||||
$this->primaryKey = new PrimaryKeyInfo($row2['attname']);
|
||||
}
|
||||
$this->primaryKey->addColumn($this->columns[ $row2['attname'] ]);
|
||||
} // foreach ($arrColumns as $intColNum)
|
||||
}
|
||||
$this->pkLoaded = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user