Skip to content

Commit

Permalink
Fluent: exports limit & offset as %lmt and %ofs [Closes #82]
Browse files Browse the repository at this point in the history
Also fixes 20f2093 on MSSQL
  • Loading branch information
dg committed Oct 26, 2015
1 parent 70c6840 commit c26201c
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 23 deletions.
18 changes: 10 additions & 8 deletions src/Dibi/Fluent.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,11 +319,10 @@ public function execute($return = NULL)
public function fetch()
{
if ($this->command === 'SELECT' && !$this->clauses['LIMIT']) {
$result = $this->query($this->limit(1)->_export())->fetch();
$this->removeClause('LIMIT');
return $result;
return $this->query($this->_export(NULL, ['%lmt', 1]))->fetch();
} else {
return $this->query($this->_export())->fetch();
}
return $this->query($this->_export())->fetch();
}


Expand All @@ -334,11 +333,10 @@ public function fetch()
public function fetchSingle()
{
if ($this->command === 'SELECT' && !$this->clauses['LIMIT']) {
$result = $this->query($this->limit(1)->_export())->fetchSingle();
$this->removeClause('LIMIT');
return $result;
return $this->query($this->_export(NULL, ['%lmt', 1]))->fetchSingle();
} else {
return $this->query($this->_export())->fetchSingle();
}
return $this->query($this->_export())->fetchSingle();
}


Expand Down Expand Up @@ -459,6 +457,10 @@ protected function _export($clause = NULL, $args = [])
{
if ($clause === NULL) {
$data = $this->clauses;
if ($this->command === 'SELECT' && ($data['LIMIT'] || $data['OFFSET'])) {
$args = array_merge(['%lmt %ofs', $data['LIMIT'][0], $data['OFFSET'][0]], $args);
unset($data['LIMIT'], $data['OFFSET']);
}

} else {
$clause = self::$normalizer->$clause;
Expand Down
101 changes: 101 additions & 0 deletions tests/dibi/Fluent.fetch.limit.mssql.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

use Tester\Assert;

require __DIR__ . '/bootstrap.php';


class MockDriver extends Dibi\Drivers\SqlsrvDriver
{
function __construct()
{}

function connect(array & $config)
{}

function query($sql)
{
return $this;
}

function getResultColumns()
{
return [];
}

function fetch($assoc)
{
return FALSE;
}
}

$config['driver'] = new MockDriver;
$conn = new Dibi\Connection($config);


// fetch & limit
$fluent = $conn->select('*')
->from('customers')
->limit(1)
->orderBy('customer_id');

Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
(string) $fluent
);


$fluent->fetch();
Assert::same(
'SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T ',
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
dibi::$sql
);
$fluent->fetchAll(0, 3);
Assert::same(
reformat('SELECT TOP 3 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
dibi::$sql
);
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
(string) $fluent
);


$fluent->limit(0);
$fluent->fetch();
Assert::same(
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
dibi::$sql
);
Assert::same(
reformat('SELECT TOP 0 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
(string) $fluent
);


$fluent->removeClause('limit');
$fluent->removeClause('offset');
$fluent->fetch();
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT TOP 1 * FROM ( SELECT * FROM [customers] ORDER BY [customer_id]) AS T '),
dibi::$sql
);
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id]'),
(string) $fluent
);
31 changes: 18 additions & 13 deletions tests/dibi/Fluent.fetch.limit.phpt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/**
* @dataProvider ../databases.ini
* @dataProvider ../databases.ini mysql
*/

use Tester\Assert;
Expand All @@ -20,70 +20,75 @@ $fluent = $conn->select('*')
->orderBy('customer_id');

Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
(string) $fluent
);


$fluent->fetch();
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
dibi::$sql
);
$fluent->fetchAll(2, 3);
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 3 OFFSET 2'),
dibi::$sql
);
Assert::same(
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
(string) $fluent
);


$fluent->limit(0);
$fluent->fetch();
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 0 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 0 OFFSET 3'),
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 0 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 0 OFFSET 3'),
dibi::$sql
);
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 0 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 0 OFFSET 3'),
(string) $fluent
);


$fluent->removeClause('limit');
$fluent->fetch();
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1 OFFSET 3'),
dibi::$sql
);
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 3'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 18446744073709551615 OFFSET 3'),
(string) $fluent
);


$fluent->removeClause('offset');
$fluent->fetch();
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1'),
dibi::$sql
);
$fluent->fetchSingle();
Assert::same(
reformat('SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1'),
reformat(' SELECT * FROM [customers] ORDER BY [customer_id] LIMIT 1'),
dibi::$sql
);
Assert::same(
Expand Down
14 changes: 12 additions & 2 deletions tests/dibi/Fluent.select.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ try {
} catch (Exception $e) {
}
Assert::same(
reformat('SELECT * FROM [table] LIMIT 1'),
reformat(' SELECT * FROM [table] LIMIT 1'),
dibi::$sql
);

Expand All @@ -102,7 +102,7 @@ $fluent = $conn->select('*')
->offset(0);

Assert::same(
reformat('SELECT * , (SELECT count(*) FROM [precteni] AS [P] WHERE P.id_clanku = C.id_clanku) FROM [clanky] AS [C] WHERE id_clanku=123 LIMIT 1 OFFSET 0'),
reformat(' SELECT * , (SELECT count(*) FROM [precteni] AS [P] WHERE P.id_clanku = C.id_clanku) FROM [clanky] AS [C] WHERE id_clanku=123 LIMIT 1'),
(string) $fluent
);

Expand Down Expand Up @@ -141,3 +141,13 @@ Assert::same(
reformat('SELECT * FROM [me] AS [t] WHERE col > 10 AND ([x] = \'a\') AND (b) AND (c)'),
(string) $fluent
);


$fluent = $conn->select('*')
->limit(' 1; DROP TABLE users')
->offset(' 1; DROP TABLE users');

Assert::same(
reformat(' SELECT * LIMIT 1 OFFSET 1'),
(string) $fluent
);

0 comments on commit c26201c

Please sign in to comment.