mirror of
https://github.com/atlanticbiomedical/portal-legacy.git
synced 2025-07-02 01:47:28 -04:00
206 lines
6.5 KiB
PHP
Executable File
206 lines
6.5 KiB
PHP
Executable File
<?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');
|
|
}
|
|
|
|
}
|