1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-03 12:47:33 +02:00

- added DibiDataSource as default implementation of IDataSource

- new modifiers %lmt %ofs
- removed old modifier %p (alias for %sql)
This commit is contained in:
David Grudl
2008-01-18 02:57:43 +00:00
parent c41167d49f
commit f6b781f12d
9 changed files with 204 additions and 18 deletions

View File

@@ -44,6 +44,7 @@ require_once dirname(__FILE__) . '/libs/DibiTranslator.php';
require_once dirname(__FILE__) . '/libs/DibiLogger.php';
require_once dirname(__FILE__) . '/libs/DibiVariable.php';
require_once dirname(__FILE__) . '/libs/DibiTable.php';
require_once dirname(__FILE__) . '/libs/DibiDataSource.php';
@@ -396,7 +397,7 @@ class dibi
/**
* Import SQL dump from file - extreme fast!
*
* @param filename
* @param string filename
* @return int count of sql commands
*/
public static function loadFile($file)

View File

@@ -391,7 +391,7 @@ class DibiConnection extends NObject
/**
* Import SQL dump from file - extreme fast!
*
* @param filename
* @param string filename
* @return int count of sql commands
*/
public function loadFile($file)

View File

@@ -0,0 +1,93 @@
<?php
/**
* dibi - tiny'n'smart database abstraction layer
* ----------------------------------------------
*
* Copyright (c) 2005, 2008 David Grudl aka -dgx- (http://www.dgx.cz)
*
* This source file is subject to the "dibi license" that is bundled
* with this package in the file license.txt.
*
* For more information please see http://dibiphp.com/
*
* @copyright Copyright (c) 2005, 2008 David Grudl
* @license http://dibiphp.com/license dibi license
* @link http://dibiphp.com/
* @package dibi
*/
/**
* Default implementation of IDataSource for dibi
*
* @author David Grudl
* @copyright Copyright (c) 2005, 2008 David Grudl
* @package dibi
* @version $Revision$ $Date$
*/
class DibiDataSource extends NObject implements IDataSource
{
/** @var DibiConnection */
private $connection;
/** @var string */
private $sql;
/** @var int */
private $count;
/**
* @param string SQL command or table name, as data source
* @param DibiConnection connection
*/
public function __construct($sql, DibiConnection $connection = NULL)
{
if (strpos($sql, ' ') === FALSE) {
// table name
$this->sql = $sql;
} else {
// SQL command
$this->sql = '(' . $sql . ') AS [source]';
}
$this->connection = $connection === NULL ? dibi::getConnection() : $connection;
}
/**
* @param int offset
* @param int limit
* @param array columns
* @return ArrayIterator
*/
public function getIterator($offset = NULL, $limit = NULL, $cols = NULL)
{
return $this->connection->query('
SELECT %n', ($cols === NULL ? '*' : $cols), '
FROM %sql', $this->sql, '
%ofs %lmt', $offset, $limit
);
}
/**
* @return int
*/
public function count()
{
if ($this->count === NULL) {
$this->count = $this->connection->query('
SELECT COUNT(*)
FROM %sql', $this->sql
)->fetchSingle();
}
return $this->count;
}
}

View File

@@ -41,7 +41,7 @@
* @package dibi
* @version $Revision$ $Date$
*/
class DibiResult extends NObject implements IteratorAggregate, Countable
class DibiResult extends NObject implements IDataSource
{
/**
* IDibiDriver

View File

@@ -141,14 +141,8 @@ abstract class DibiTable extends NObject
*/
public function insert($data)
{
if (is_object($data)) {
$data = (array) $data;
} elseif (!is_array($data)) {
throw new DibiException('Dataset must be array or anonymous object');
}
$this->connection->query(
'INSERT INTO %n', $this->name, '%v', $data
'INSERT INTO %n', $this->name, '%v', $this->prepare($data)
);
return $this->connection->insertId();
}
@@ -163,15 +157,9 @@ abstract class DibiTable extends NObject
*/
public function update($where, $data)
{
if (is_object($data)) {
$data = (array) $data;
} elseif (!is_array($data)) {
throw new DibiException('Dataset must be array or anonymous object');
}
$this->connection->query(
'UPDATE %n', $this->name,
'SET %a', $data,
'SET %a', $this->prepare($data),
'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $where, ')'
);
return $this->connection->affectedRows();
@@ -266,6 +254,24 @@ abstract class DibiTable extends NObject
/**
* User data pre-processing
* @param array|object
* @return array
*/
protected function prepare($data)
{
if (is_object($data)) {
return (array) $data;
} elseif (is_array($data)) {
return $data;
}
throw new DibiException('Dataset must be array or anonymous object');
}
/**
* User DibiResult post-processing
* @param DibiResult

View File

@@ -53,6 +53,12 @@ final class DibiTranslator extends NObject
/** @var int */
private $ifLevelStart;
/** @var int */
public $limit;
/** @var int */
public $offset;
public function __construct(IDibiDriver $driver)
@@ -70,6 +76,8 @@ final class DibiTranslator extends NObject
*/
public function translate(array $args)
{
$this->limit = -1;
$this->offset = 0;
$this->hasError = FALSE;
$commandIns = NULL;
$lastArr = NULL;
@@ -140,6 +148,11 @@ final class DibiTranslator extends NObject
// TODO: check !!!
$this->sql = preg_replace('#\x00.*?\x00#s', '', $this->sql);
// apply limit
if ($this->limit > -1 || $this->offset > 0) {
$this->driver->applyLimit($this->sql, $this->limit, $this->offset);
}
return !$this->hasError;
}
@@ -172,6 +185,7 @@ final class DibiTranslator extends NObject
case 'l': // LIST
$kx = NULL;
// break intentionally omitted
case 'v': // VALUES
foreach ($value as $k => $v) {
// split into identifier & modifier
@@ -251,7 +265,6 @@ final class DibiTranslator extends NObject
return $this->delimite($value);
case 'sql':// preserve as SQL
case 'p': // back compatibility
$value = (string) $value;
// speed-up - is regexp required?
@@ -281,6 +294,14 @@ final class DibiTranslator extends NObject
substr($value, $toSkip)
);
case 'lmt': // apply limit
if ($value !== NULL) $this->limit = (int) $value;
return '';
case 'ofs': // apply offset
if ($value !== NULL) $this->offset = (int) $value;
return '';
case 'a':
case 'v':
$this->hasError = TRUE;

View File

@@ -39,6 +39,20 @@ interface IDibiVariable
/**
* Provides an interface between a dataset and data-aware components
* @package dibi
*/
interface IDataSource extends Countable, IteratorAggregate
{
//function IteratorAggregate::getIterator();
//function Countable::count();
}
/**
* dibi driver interface
*

34
examples/apply-limit.php Normal file
View File

@@ -0,0 +1,34 @@
<h1>dibi apply limit/offset example</h1>
<pre>
<?php
require_once '../dibi/dibi.php';
dibi::connect(array(
'driver' => 'sqlite',
'database' => 'sample.sdb',
));
// no limit
$res = dibi::query('SELECT * FROM [products]');
foreach ($res as $n => $row) {
print_r($row);
}
echo '<hr>';
// with limit = 2
$res = dibi::query('SELECT * FROM [products] %lmt', 2);
foreach ($res as $n => $row) {
print_r($row);
}
echo '<hr>';
// with limit = 2, offset = 1
$res = dibi::query('SELECT * FROM [products] %lmt %ofs', 2, 1);
foreach ($res as $n => $row) {
print_r($row);
}

View File

@@ -15,3 +15,20 @@ ERROR: [1] near "FROM": syntax error
-- driver: ;
-- 2007-11-15 01:19:00
OK: SELECT * FROM [customers] WHERE [customer_id] = 1;
-- rows: 1
-- takes: 0.319 ms
-- driver: sqlite
-- 2008-01-18 03:57:19
OK: SELECT * FROM [customers] WHERE [customer_id] < 5;
-- rows: 4
-- takes: 0.384 ms
-- driver: sqlite
-- 2008-01-18 03:57:19
ERROR: [2] sqlite_query(): near "FROM": syntax error
-- SQL: SELECT FROM [customers] WHERE [customer_id] < 38
-- driver: ;
-- 2008-01-18 03:57:19