mirror of
https://github.com/dg/dibi.git
synced 2025-08-12 09:04:24 +02:00
update to 0.5alpha
This commit is contained in:
101
dibi/libs/date.type.demo.php
Normal file
101
dibi/libs/date.type.demo.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* dibi - Database Abstraction Layer according to dgx
|
||||
* --------------------------------------------------
|
||||
*
|
||||
* This source file is subject to the GNU GPL license.
|
||||
*
|
||||
* @author David Grudl aka -dgx- <dave@dgx.cz>
|
||||
* @link http://texy.info/dibi/
|
||||
* @copyright Copyright (c) 2005-2006 David Grudl
|
||||
* @license GNU GENERAL PUBLIC LICENSE
|
||||
* @package dibi
|
||||
* @category Database
|
||||
* @version 0.5alpha (2006-05-26) for PHP5
|
||||
*/
|
||||
|
||||
|
||||
// security - include dibi.php, not this file
|
||||
if (!defined('dibi')) die();
|
||||
|
||||
|
||||
// required since PHP 5.1.0
|
||||
// todo:
|
||||
if (function_exists('date_default_timezone_set'))
|
||||
date_default_timezone_set('Europe/Prague'); // or 'GMT'
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Pseudotype for UNIX timestamp representation
|
||||
*/
|
||||
class TDate implements IDibiVariable
|
||||
{
|
||||
/**
|
||||
* Unix timestamp
|
||||
* @var int
|
||||
*/
|
||||
protected $time;
|
||||
|
||||
|
||||
|
||||
public function __construct($time = NULL)
|
||||
{
|
||||
if ($time === NULL)
|
||||
$this->time = time(); // current time
|
||||
|
||||
elseif (is_string($time))
|
||||
$this->time = strtotime($time); // try convert to timestamp
|
||||
|
||||
else
|
||||
$this->time = (int) $time;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Format for SQL
|
||||
*
|
||||
* @param object destination DibiDriver
|
||||
* @param string optional modifier
|
||||
* @return string
|
||||
*/
|
||||
public function toSQL($driver, $modifier = NULL)
|
||||
{
|
||||
return date(
|
||||
$driver->formats['date'], // format according to driver's spec.
|
||||
$this->time
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getTimeStamp()
|
||||
{
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Pseudotype for datetime representation
|
||||
*/
|
||||
class TDateTime extends TDate
|
||||
{
|
||||
|
||||
public function toSQL($driver, $modifier = NULL)
|
||||
{
|
||||
return date(
|
||||
$driver->formats['datetime'], // format according to driver's spec.
|
||||
$this->time
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
164
dibi/libs/driver.php
Normal file
164
dibi/libs/driver.php
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* dibi - Database Abstraction Layer according to dgx
|
||||
* --------------------------------------------------
|
||||
*
|
||||
* This source file is subject to the GNU GPL license.
|
||||
*
|
||||
* @author David Grudl aka -dgx- <dave@dgx.cz>
|
||||
* @link http://texy.info/dibi/
|
||||
* @copyright Copyright (c) 2005-2006 David Grudl
|
||||
* @license GNU GENERAL PUBLIC LICENSE
|
||||
* @package dibi
|
||||
* @category Database
|
||||
* @version 0.5alpha (2006-05-26) for PHP5
|
||||
*/
|
||||
|
||||
|
||||
// security - include dibi.php, not this file
|
||||
if (!defined('dibi')) die();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* dibi Common Driver
|
||||
*
|
||||
*/
|
||||
abstract class DibiDriver
|
||||
{
|
||||
/**
|
||||
* Current connection configuration
|
||||
* @var array
|
||||
*/
|
||||
protected
|
||||
$config;
|
||||
|
||||
/**
|
||||
* Describes how convert some datatypes to SQL command
|
||||
* @var array
|
||||
*/
|
||||
public $formats = array(
|
||||
'NULL' => "NULL", // NULL
|
||||
'TRUE' => "1", // boolean true
|
||||
'FALSE' => "0", // boolean false
|
||||
'date' => "'Y-m-d'", // format used by date()
|
||||
'datetime' => "'Y-m-d H:i:s'", // format used by date()
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* DibiDriver factory: creates object and connects to a database
|
||||
*
|
||||
* @param array connect configuration
|
||||
* @return bool|object DibiDriver object on success, FALSE or Exception on failure
|
||||
*/
|
||||
abstract static public function connect($config);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Driver initialization
|
||||
*
|
||||
* @param array connect configuration
|
||||
*/
|
||||
protected function __construct($config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the configuration descriptor used by connect() to connect to database.
|
||||
* @see connect()
|
||||
* @return array
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Executes the SQL query
|
||||
*
|
||||
* @param string SQL statement.
|
||||
* @return object|bool Result set object or TRUE on success, Exception on failure
|
||||
*/
|
||||
abstract public function query($sql);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number of affected rows by the last INSERT, UPDATE or DELETE query
|
||||
*
|
||||
* @return int number of rows or FALSE on error
|
||||
*/
|
||||
abstract public function affectedRows();
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query
|
||||
* @return int|bool int on success or FALSE on failure
|
||||
*/
|
||||
abstract public function insertId();
|
||||
|
||||
|
||||
/**
|
||||
* Begins a transaction (if supported).
|
||||
*/
|
||||
abstract public function begin();
|
||||
|
||||
|
||||
/**
|
||||
* Commits statements in a transaction.
|
||||
*/
|
||||
abstract public function commit();
|
||||
|
||||
|
||||
/**
|
||||
* Rollback changes in a transaction.
|
||||
*/
|
||||
abstract public function rollback();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Escapes the string
|
||||
* @param string unescaped string
|
||||
* @param bool quote string?
|
||||
* @return string escaped and optionally quoted string
|
||||
*/
|
||||
abstract public function escape($value, $appendQuotes = FALSE);
|
||||
|
||||
|
||||
/**
|
||||
* Quotes SQL identifier (table's or column's name, etc.)
|
||||
* @param string identifier
|
||||
* @return string quoted identifier
|
||||
*/
|
||||
abstract public function quoteName($value);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets a information of the current database.
|
||||
*
|
||||
* @return DibiMetaData
|
||||
*/
|
||||
abstract public function getMetaData();
|
||||
|
||||
|
||||
|
||||
|
||||
} // class DibiDriver
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
67
dibi/libs/exception.php
Normal file
67
dibi/libs/exception.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* dibi - Database Abstraction Layer according to dgx
|
||||
* --------------------------------------------------
|
||||
*
|
||||
* This source file is subject to the GNU GPL license.
|
||||
*
|
||||
* @author David Grudl aka -dgx- <dave@dgx.cz>
|
||||
* @link http://texy.info/dibi/
|
||||
* @copyright Copyright (c) 2005-2006 David Grudl
|
||||
* @license GNU GENERAL PUBLIC LICENSE
|
||||
* @package dibi
|
||||
* @category Database
|
||||
* @version 0.5alpha (2006-05-26) for PHP5
|
||||
*/
|
||||
|
||||
|
||||
// security - include dibi.php, not this file
|
||||
if (!defined('dibi')) die();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* dibi exception class
|
||||
*
|
||||
*/
|
||||
class DibiException extends Exception
|
||||
{
|
||||
private
|
||||
$info;
|
||||
|
||||
|
||||
public function __construct($message, $info=NULL) {
|
||||
|
||||
$this->info = $info;
|
||||
|
||||
if (isset($info['message']))
|
||||
$message = "$message: $info[message]";
|
||||
/*
|
||||
if (isset($info['sql']))
|
||||
$message .= "\n[SQL] $info[sql]";
|
||||
*/
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getSql()
|
||||
{
|
||||
return @$this->info['sql'];
|
||||
}
|
||||
|
||||
|
||||
} // class DibiException
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function is_error($var)
|
||||
{
|
||||
return ($var === FALSE) || ($var instanceof Exception);
|
||||
}
|
||||
|
||||
|
||||
?>
|
295
dibi/libs/parser.php
Normal file
295
dibi/libs/parser.php
Normal file
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* dibi - Database Abstraction Layer according to dgx
|
||||
* --------------------------------------------------
|
||||
*
|
||||
* This source file is subject to the GNU GPL license.
|
||||
*
|
||||
* @author David Grudl aka -dgx- <dave@dgx.cz>
|
||||
* @link http://texy.info/dibi/
|
||||
* @copyright Copyright (c) 2005-2006 David Grudl
|
||||
* @license GNU GENERAL PUBLIC LICENSE
|
||||
* @package dibi
|
||||
* @category Database
|
||||
* @version 0.5alpha (2006-05-26) for PHP5
|
||||
*/
|
||||
|
||||
|
||||
// security - include dibi.php, not this file
|
||||
if (!defined('dibi')) die();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* dibi parser
|
||||
*
|
||||
*/
|
||||
class DibiParser
|
||||
{
|
||||
private
|
||||
$modifier,
|
||||
$hasError,
|
||||
$driver;
|
||||
|
||||
|
||||
/**
|
||||
* Generates SQL
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
public function parse($driver, $args)
|
||||
{
|
||||
$sql = '';
|
||||
$this->driver = $driver;
|
||||
$this->modifier = 0;
|
||||
$this->hasError = false;
|
||||
$command = null;
|
||||
$lastString = null;
|
||||
|
||||
foreach ($args as $index => $arg) {
|
||||
$sql .= ' '; // always add simple space
|
||||
|
||||
|
||||
// array processing (with or without modifier)
|
||||
if (is_array($arg)) {
|
||||
// determine type: set | values | list
|
||||
if ($this->modifier) {
|
||||
$type = $this->modifier;
|
||||
$this->modifier = false;
|
||||
} else {
|
||||
// autodetect
|
||||
if (is_int(key($arg)))
|
||||
$type = 'L'; // LIST
|
||||
else {
|
||||
if (!$command)
|
||||
$command = strtoupper(substr(ltrim($args[0]), 0, 6));
|
||||
|
||||
$type = $command == 'UPDATE' ? 'S' : 'V'; // SET | VALUES
|
||||
}
|
||||
}
|
||||
|
||||
// build array
|
||||
$vx = $kx = array();
|
||||
switch ($type) {
|
||||
case 'S': // SET
|
||||
foreach ($arg as $k => $v)
|
||||
$vx[] = $this->driver->quoteName($k) . '=' . $this->formatValue($v);
|
||||
|
||||
$sql .= implode(', ', $vx);
|
||||
break;
|
||||
|
||||
case 'V': // VALUES
|
||||
foreach ($arg as $k => $v) {
|
||||
$kx[] = $this->driver->quoteName($k);
|
||||
$vx[] = $this->formatValue($v);
|
||||
}
|
||||
|
||||
$sql .= '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
|
||||
break;
|
||||
|
||||
case 'L': // LIST
|
||||
foreach ($arg as $k => $v)
|
||||
$vx[] = $this->formatValue($v);
|
||||
|
||||
$sql .= implode(', ', $vx);
|
||||
break;
|
||||
|
||||
case 'N': // NAMES
|
||||
foreach ($arg as $v)
|
||||
$vx[] = $this->driver->quoteName($v);
|
||||
|
||||
$sql .= implode(', ', $vx);
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->hasError = true;
|
||||
$sql .= "**Unknown modifier %$type**";
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// after-modifier procession
|
||||
if ($this->modifier) {
|
||||
if ($arg instanceof IDibiVariable) {
|
||||
$sql .= $arg->toSql($this->driver, $this->modifier);
|
||||
$this->modifier = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_scalar($arg) && !is_null($arg)) { // array is already processed
|
||||
$this->hasError = true;
|
||||
$this->modifier = false;
|
||||
$sql .= '**Unexpected '.gettype($arg).'**';
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($this->modifier) {
|
||||
case "s": // string
|
||||
$sql .= $this->driver->escape($arg, TRUE);
|
||||
break;
|
||||
case 'T': // date
|
||||
$sql .= date($this->driver->formats['date'], is_string($arg) ? strtotime($arg) : $arg);
|
||||
break;
|
||||
case 't': // datetime
|
||||
$sql .= date($this->driver->formats['datetime'], is_string($arg) ? strtotime($arg) : $arg);
|
||||
break;
|
||||
case 'b': // boolean
|
||||
$sql .= $arg ? $this->driver->formats['TRUE'] : $this->driver->formats['FALSE'];
|
||||
break;
|
||||
case 'i':
|
||||
case 'u': // unsigned int
|
||||
case 'd': // signed int
|
||||
$sql .= (string) (int) $arg;
|
||||
break;
|
||||
case 'f': // float
|
||||
$sql .= (string) (float) $arg; // something like -9E-005 is accepted by SQL
|
||||
break;
|
||||
case 'n': // identifier name
|
||||
$sql .= $this->driver->quoteName($arg);
|
||||
break;
|
||||
default:
|
||||
$this->hasError = true;
|
||||
$sql .= "**Unknown modifier %$this->modifier**";
|
||||
}
|
||||
|
||||
$this->modifier = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// simple string means SQL
|
||||
if (is_string($arg)) {
|
||||
// double string warning
|
||||
// (problematic with dibi::queryStart & dibi::queryAdd
|
||||
// if ($lastString === $index-1)
|
||||
// trigger_error("Is seems there is error in SQL near '$arg'.", E_USER_WARNING);
|
||||
|
||||
$lastString = $index;
|
||||
|
||||
// speed-up - is regexp required?
|
||||
$toSkip = strcspn($arg, '`[\'"%');
|
||||
|
||||
if ($toSkip == strlen($arg)) {
|
||||
$sql .= $arg;
|
||||
} else {
|
||||
$sql .= substr($arg, 0, $toSkip)
|
||||
. preg_replace_callback('/
|
||||
(?=`|\[|\'|"|%) ## speed-up
|
||||
(?:
|
||||
`(.+?)`| ## 1) `identifier`
|
||||
\[(.+?)\]| ## 2) [identifier]
|
||||
(\')((?:\'\'|[^\'])*)\'| ## 3,4) string
|
||||
(")((?:""|[^"])*)"| ## 5,6) "string"
|
||||
%([a-zA-Z])$| ## 7) right modifier
|
||||
(\'|") ## 8) lone-quote
|
||||
)/xs',
|
||||
array($this, 'callback'),
|
||||
substr($arg, $toSkip)
|
||||
);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// default processing
|
||||
$sql .= $this->formatValue($arg);
|
||||
|
||||
} // for
|
||||
|
||||
|
||||
if ($this->hasError)
|
||||
return new DibiException('Errors during generating SQL', array('sql' => $sql));
|
||||
|
||||
return trim($sql);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private function formatValue($value)
|
||||
{
|
||||
if (is_string($value))
|
||||
return $this->driver->escape($value, TRUE);
|
||||
|
||||
if (is_int($value) || is_float($value))
|
||||
return (string) $value; // something like -9E-005 is accepted by SQL
|
||||
|
||||
if (is_bool($value))
|
||||
return $value ? $this->driver->formats['TRUE'] : $this->driver->formats['FALSE'];
|
||||
|
||||
if (is_null($value))
|
||||
return $this->driver->formats['NULL'];
|
||||
|
||||
if ($value instanceof IDibiVariable)
|
||||
return $value->toSql($this->driver);
|
||||
|
||||
$this->hasError = true;
|
||||
return '**Unsupported type '.gettype($value).'**';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* PREG callback for @see self::translate()
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
private function callback($matches)
|
||||
{
|
||||
// [1] => `ident`
|
||||
// [2] => [ident]
|
||||
// [3] => '
|
||||
// [4] => string
|
||||
// [5] => "
|
||||
// [6] => string
|
||||
// [7] => right modifier
|
||||
// [8] => lone-quote
|
||||
|
||||
if ($matches[1]) // SQL identifiers: `ident`
|
||||
return $this->driver->quoteName($matches[1]);
|
||||
|
||||
if ($matches[2]) // SQL identifiers: [ident]
|
||||
return $this->driver->quoteName($matches[2]);
|
||||
|
||||
if ($matches[3]) // SQL strings: '....'
|
||||
return $this->driver->escape( strtr($matches[4], array("''" => "'")), true);
|
||||
|
||||
if ($matches[5]) // SQL strings: "..."
|
||||
return $this->driver->escape( strtr($matches[6], array('""' => '"')), true);
|
||||
|
||||
if ($matches[7]) { // modifier
|
||||
$this->modifier = $matches[7];
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($matches[8]) { // string quote
|
||||
return '**Alone quote**';
|
||||
$this->hasError = true;
|
||||
}
|
||||
|
||||
die('this should be never executed');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // class DibiParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
396
dibi/libs/resultset.php
Normal file
396
dibi/libs/resultset.php
Normal file
@@ -0,0 +1,396 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* dibi - Database Abstraction Layer according to dgx
|
||||
* --------------------------------------------------
|
||||
*
|
||||
* This source file is subject to the GNU GPL license.
|
||||
*
|
||||
* @author David Grudl aka -dgx- <dave@dgx.cz>
|
||||
* @link http://texy.info/dibi/
|
||||
* @copyright Copyright (c) 2005-2006 David Grudl
|
||||
* @license GNU GENERAL PUBLIC LICENSE
|
||||
* @package dibi
|
||||
* @category Database
|
||||
* @version 0.5alpha (2006-05-26) for PHP5
|
||||
*/
|
||||
|
||||
|
||||
// security - include dibi.php, not this file
|
||||
if (!defined('dibi')) die();
|
||||
|
||||
|
||||
|
||||
// PHP < 5.1 compatibility
|
||||
if (!interface_exists('Countable', false)) {
|
||||
interface Countable
|
||||
{
|
||||
function count();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* dibi result-set abstract class
|
||||
*
|
||||
* <code>
|
||||
* $result = dibi::query('SELECT * FROM [table]');
|
||||
* $value = $result->fetchSingle();
|
||||
* $all = $result->fetchAll();
|
||||
* $assoc = $result->fetchAll('id');
|
||||
* $assoc = $result->fetchAll('active', 'id');
|
||||
* unset($result);
|
||||
* </code>
|
||||
*/
|
||||
abstract class DibiResult implements IteratorAggregate, Countable
|
||||
{
|
||||
/**
|
||||
* Column type in relation to PHP native type
|
||||
*/
|
||||
const
|
||||
FIELD_TEXT = 's', // as 'string'
|
||||
FIELD_BINARY = 'b',
|
||||
FIELD_BOOL = 'l', // as 'logical'
|
||||
FIELD_INTEGER = 'i',
|
||||
FIELD_FLOAT = 'f',
|
||||
FIELD_DATE = 'd',
|
||||
FIELD_DATETIME = 't',
|
||||
FIELD_UNKNOWN = '?',
|
||||
|
||||
// special
|
||||
FIELD_COUNTER = 'c'; // counter or autoincrement, is integer
|
||||
|
||||
|
||||
/**
|
||||
* Describes columns types
|
||||
* @var array
|
||||
*/
|
||||
protected $convert;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Moves cursor position without fetching row
|
||||
* @param int the 0-based cursor pos to seek to
|
||||
* @return boolean TRUE on success, FALSE if unable to seek to specified record
|
||||
*/
|
||||
abstract public function seek($row);
|
||||
|
||||
/**
|
||||
* Returns the number of rows in a result set
|
||||
* @return int
|
||||
*/
|
||||
abstract public function rowCount();
|
||||
|
||||
/**
|
||||
* Gets an array of field names
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getFields();
|
||||
|
||||
/**
|
||||
* Gets an array of meta informations about column
|
||||
* @param string column name
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getMetaData($field);
|
||||
|
||||
/**
|
||||
* Acquires ....
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function detectTypes();
|
||||
|
||||
/**
|
||||
* Frees the resources allocated for this result set
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function free();
|
||||
|
||||
/**
|
||||
* Fetches the row at current position and moves the internal cursor to the next position
|
||||
* internal usage only
|
||||
* @return array|FALSE array() on success, FALSE if no next record
|
||||
*/
|
||||
abstract protected function doFetch();
|
||||
|
||||
|
||||
/**
|
||||
* Fetches the row at current position, process optional type conversion
|
||||
* and moves the internal cursor to the next position
|
||||
* @return array|FALSE array() on success, FALSE if no next record
|
||||
*/
|
||||
final public function fetch()
|
||||
{
|
||||
$rec = $this->doFetch();
|
||||
if (!is_array($rec))
|
||||
return FALSE;
|
||||
|
||||
// types-converting?
|
||||
if ($t = $this->convert) { // little speed-up
|
||||
foreach ($rec as $key => $value) {
|
||||
if (isset($t[$key]))
|
||||
$rec[$key] = $this->convert($value, $t[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $rec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Like fetch(), but returns only first field
|
||||
* @return mixed value on success, FALSE if no next record
|
||||
*/
|
||||
final function fetchSingle()
|
||||
{
|
||||
$rec = $this->doFetch();
|
||||
if (!is_array($rec))
|
||||
return FALSE;
|
||||
|
||||
// types-converting?
|
||||
if ($t = $this->convert) { // little speed-up
|
||||
$value = reset($rec);
|
||||
$key = key($rec);
|
||||
return isset($t[$key])
|
||||
? $this->convert($value, $t[$key])
|
||||
: $value;
|
||||
}
|
||||
|
||||
return reset($rec);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fetches all records from table. Records , but returns only first field
|
||||
* @param string associative colum [, param, ... ]
|
||||
* @return array
|
||||
*/
|
||||
final function fetchAll()
|
||||
{
|
||||
@$this->seek(0);
|
||||
$rec = $this->fetch();
|
||||
if (!$rec)
|
||||
return array(); // empty resultset
|
||||
|
||||
$assocBy = func_get_args();
|
||||
$arr = array();
|
||||
|
||||
if (!$assocBy) { // no associative array
|
||||
$value = count($rec) == 1 ? key($rec) : NULL;
|
||||
do {
|
||||
$arr[] = $value === NULL ? $rec : $rec[$value];
|
||||
} while ($rec = $this->fetch());
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
do { // make associative arrays
|
||||
foreach ($assocBy as $n => $assoc) {
|
||||
$val[$n] = $rec[$assoc];
|
||||
unset($rec[$assoc]);
|
||||
}
|
||||
|
||||
foreach ($assocBy as $n => $assoc) {
|
||||
if ($n == 0)
|
||||
$tmp = &$arr[ $val[$n] ];
|
||||
else
|
||||
$tmp = &$tmp[$assoc][ $val[$n] ];
|
||||
|
||||
if ($tmp === NULL)
|
||||
$tmp = $rec;
|
||||
}
|
||||
} while ($rec = $this->fetch());
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fetches all records from table like $key => $value pairs
|
||||
* @return array
|
||||
*/
|
||||
final function fetchPairs($key, $value)
|
||||
{
|
||||
@$this->seek(0);
|
||||
$rec = $this->fetch();
|
||||
if (!$rec)
|
||||
return array(); // empty resultset
|
||||
|
||||
$arr = array();
|
||||
do {
|
||||
$arr[ $rec[$key] ] = $rec[$value];
|
||||
} while ($rec = $this->fetch());
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Automatically frees the resources allocated for this result set
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
@$this->free();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function setType($field, $type = NULL)
|
||||
{
|
||||
if ($field === TRUE)
|
||||
$this->detectTypes();
|
||||
|
||||
elseif (is_array($field))
|
||||
$this->convert = $field;
|
||||
|
||||
else
|
||||
$this->convert[$field] = $type;
|
||||
}
|
||||
|
||||
|
||||
/** is this needed? */
|
||||
public function getType($field)
|
||||
{
|
||||
return isset($this->convert[$field]) ? $this->convert[$field] : NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function convert($value, $type)
|
||||
{
|
||||
if ($value === NULL || $value === FALSE)
|
||||
return $value;
|
||||
|
||||
static $conv = array(
|
||||
self::FIELD_TEXT => 'string',
|
||||
self::FIELD_BINARY => 'string',
|
||||
self::FIELD_BOOL => 'bool',
|
||||
self::FIELD_INTEGER => 'int',
|
||||
self::FIELD_FLOAT => 'float',
|
||||
self::FIELD_COUNTER => 'int',
|
||||
);
|
||||
|
||||
if (isset($conv[$type])) {
|
||||
settype($value, $conv[$type]);
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($type == self::FIELD_DATE)
|
||||
return new TDate($value); // !!! experimental
|
||||
|
||||
if ($type == self::FIELD_DATETIME)
|
||||
return new TDateTime($value); // !!! experimental
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/** these are the required IteratorAggregate functions */
|
||||
public function getIterator($offset = NULL, $count = NULL)
|
||||
{
|
||||
return new DibiResultIterator($this, $offset, $count);
|
||||
}
|
||||
/** end required IteratorAggregate functions */
|
||||
|
||||
|
||||
/** these are the required Countable functions */
|
||||
public function count()
|
||||
{
|
||||
return $this->rowCount();
|
||||
}
|
||||
/** end required Countable functions */
|
||||
|
||||
} // class DibiResult
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Basic Result set iterator.
|
||||
*
|
||||
* This can be returned by DibiResult::getIterator() method or directly using foreach:
|
||||
* <code>
|
||||
* $result = dibi::query('SELECT * FROM table');
|
||||
* foreach ($result as $fields) {
|
||||
* print_r($fields);
|
||||
* }
|
||||
* unset($result);
|
||||
* </code>
|
||||
*
|
||||
* Optionally you can specify offset and limit:
|
||||
* <code>
|
||||
* foreach ($result->getIterator(2, 3) as $fields) {
|
||||
* print_r($fields);
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
class DibiResultIterator implements Iterator
|
||||
{
|
||||
private
|
||||
$result,
|
||||
$offset,
|
||||
$count,
|
||||
$record,
|
||||
$row;
|
||||
|
||||
|
||||
public function __construct(DibiResult $result, $offset = NULL, $count = NULL)
|
||||
{
|
||||
$this->result = $result;
|
||||
$this->offset = (int) $offset;
|
||||
$this->count = $count === NULL ? PHP_INT_MAX : (int) $count;
|
||||
}
|
||||
|
||||
|
||||
/** these are the required Iterator functions */
|
||||
public function rewind()
|
||||
{
|
||||
$this->row = 0;
|
||||
@$this->result->seek($this->offset);
|
||||
$this->record = $this->result->fetch();
|
||||
}
|
||||
|
||||
|
||||
public function key()
|
||||
{
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
|
||||
public function current()
|
||||
{
|
||||
return $this->record;
|
||||
}
|
||||
|
||||
|
||||
public function next()
|
||||
{
|
||||
$this->record = $this->result->fetch();
|
||||
$this->row++;
|
||||
}
|
||||
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return is_array($this->record) && ($this->row < $this->count);
|
||||
}
|
||||
/** end required Iterator functions */
|
||||
|
||||
|
||||
} // class DibiResultIterator
|
||||
|
||||
|
||||
|
||||
?>
|
Reference in New Issue
Block a user