Skip to content

Commit

Permalink
Add support for embedded AND conditions (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshmcrae authored May 13, 2019
1 parent ead8c62 commit 3855b81
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 14 deletions.
52 changes: 40 additions & 12 deletions lib/PicoDb/Builder/ConditionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,20 @@ class ConditionBuilder
private $conditions = array();

/**
* SQL OR conditions
* SQL embedded AND/OR conditions
*
* @access private
* @var OrConditionBuilder[]
* @var LogicConditionBuilder[]
*/
private $orConditions = array();
private $embeddedConditions = array();

/**
* SQL condition offset
*
* @access private
* @var int
*/
private $orConditionOffset = 0;
private $embeddedConditionOffset = 0;

/**
* Constructor
Expand Down Expand Up @@ -105,23 +105,51 @@ public function hasCondition()
*/
public function addCondition($sql)
{
if ($this->orConditionOffset > 0) {
$this->orConditions[$this->orConditionOffset]->withCondition($sql);
if ($this->embeddedConditionOffset > 0) {
$this->embeddedConditions[$this->embeddedConditionOffset]->withCondition($sql);
}
else {
$this->conditions[] = $sql;
}
}

/**
* Start AND condition
*
* @access public
*/
public function beginAnd()
{
$this->embeddedConditionOffset++;
$this->embeddedConditions[$this->embeddedConditionOffset] = new LogicConditionBuilder('AND');
}

/**
* Close AND condition
*
* @access public
*/
public function closeAnd()
{
$condition = $this->embeddedConditions[$this->embeddedConditionOffset]->build();
$this->embeddedConditionOffset--;

if ($this->embeddedConditionOffset > 0) {
$this->embeddedConditions[$this->embeddedConditionOffset]->withCondition($condition);
} else {
$this->conditions[] = $condition;
}
}

/**
* Start OR condition
*
* @access public
*/
public function beginOr()
{
$this->orConditionOffset++;
$this->orConditions[$this->orConditionOffset] = new OrConditionBuilder();
$this->embeddedConditionOffset++;
$this->embeddedConditions[$this->embeddedConditionOffset] = new LogicConditionBuilder('OR');
}

/**
Expand All @@ -131,11 +159,11 @@ public function beginOr()
*/
public function closeOr()
{
$condition = $this->orConditions[$this->orConditionOffset]->build();
$this->orConditionOffset--;
$condition = $this->embeddedConditions[$this->embeddedConditionOffset]->build();
$this->embeddedConditionOffset--;

if ($this->orConditionOffset > 0) {
$this->orConditions[$this->orConditionOffset]->withCondition($condition);
if ($this->embeddedConditionOffset > 0) {
$this->embeddedConditions[$this->embeddedConditionOffset]->withCondition($condition);
} else {
$this->conditions[] = $condition;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@
* @package PicoDb\Builder
* @author Frederic Guillot
*/
class OrConditionBuilder
class LogicConditionBuilder
{
/**
* @var string
*/
private $type;

/**
* List of SQL conditions
*
Expand All @@ -18,6 +23,16 @@ class OrConditionBuilder
*/
protected $conditions = array();

/**
* LogicConditionBuilder constructor.
*
* @param string $type
*/
public function __construct($type)
{
$this->type = $type;
}

/**
* Add new condition
*
Expand All @@ -38,6 +53,6 @@ public function withCondition($condition) {
*/
public function build()
{
return '('.implode(' OR ', $this->conditions).')';
return '('.implode(' '. $this->type .' ', $this->conditions).')';
}
}
2 changes: 2 additions & 0 deletions lib/PicoDb/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* @author Frederic Guillot
*
* @method $this addCondition($sql)
* @method $this beginAnd()
* @method $this closeAnd()
* @method $this beginOr()
* @method $this closeOr()
* @method $this eq($column, $value)
Expand Down
8 changes: 8 additions & 0 deletions tests/MysqlTableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,14 @@ public function testCustomCondition()
$this->assertEquals(array(4), $table->getConditionBuilder()->getValues());
}

public function testAndConditions()
{
$table = $this->db->table('test');

$this->assertEquals('SELECT * FROM `test` WHERE (`a` IS NOT NULL OR (`b` = ? AND `c` >= ?))', $table->beginOr()->notNull('a')->beginAnd()->eq('b', 2)->gte('c', 5)->closeAnd()->closeOr()->buildSelectQuery());
$this->assertEquals(array(2, 5), $table->getConditionBuilder()->getValues());
}

public function testOrConditions()
{
$table = $this->db->table('test');
Expand Down
8 changes: 8 additions & 0 deletions tests/PostgresTableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,14 @@ public function testCustomCondition()
$this->assertEquals(array(4), $table->getConditionBuilder()->getValues());
}

public function testAndConditions()
{
$table = $this->db->table('test');

$this->assertEquals('SELECT * FROM "test" WHERE ("a" IS NOT NULL OR ("b" = ? AND "c" >= ?))', $table->beginOr()->notNull('a')->beginAnd()->eq('b', 2)->gte('c', 5)->closeAnd()->closeOr()->buildSelectQuery());
$this->assertEquals(array(2, 5), $table->getConditionBuilder()->getValues());
}

public function testOrConditions()
{
$table = $this->db->table('test');
Expand Down
8 changes: 8 additions & 0 deletions tests/SqliteTableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ public function testCustomCondition()
$this->assertEquals(array(4), $table->getConditionBuilder()->getValues());
}

public function testAndConditions()
{
$table = $this->db->table('test');

$this->assertEquals('SELECT * FROM "test" WHERE ("a" IS NOT NULL OR ("b" = ? AND "c" >= ?))', $table->beginOr()->notNull('a')->beginAnd()->eq('b', 2)->gte('c', 5)->closeAnd()->closeOr()->buildSelectQuery());
$this->assertEquals(array(2, 5), $table->getConditionBuilder()->getValues());
}

public function testOrConditions()
{
$table = $this->db->table('test');
Expand Down

0 comments on commit 3855b81

Please sign in to comment.