-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
359 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace QueryBuilder; | ||
|
||
class Column | ||
{ | ||
public function __construct( | ||
private string $expression, | ||
private ?string $alias = null | ||
) { | ||
} | ||
|
||
public function __toString() | ||
{ | ||
if ($this->alias) { | ||
return $this->expression . ' AS ' . $this->alias; | ||
} | ||
return $this->expression; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
namespace QueryBuilder; | ||
|
||
use QueryBuilder\Join\Equals; | ||
|
||
class From | ||
{ | ||
public function __construct(private string $expression) | ||
{ | ||
} | ||
|
||
public function join(string $table, Equals $condition ) | ||
{ | ||
$this->expression .= PHP_EOL . Query::INDENT . 'JOIN ' . $table . ' ON ' . (string) $condition; | ||
} | ||
|
||
public function __toString() | ||
{ | ||
return 'FROM ' . $this->expression; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace QueryBuilder; | ||
|
||
class Join | ||
{ | ||
public function __construct(private string $table) | ||
{ | ||
$this->table = $table; | ||
} | ||
|
||
private function plop($from, $join) { | ||
|
||
} | ||
|
||
public function __toString() | ||
{ | ||
return Query::INDENT . "JOIN " . $this->table . $this->conditions(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace QueryBuilder\Join; | ||
|
||
use QueryBuilder\Column; | ||
|
||
class Equals | ||
{ | ||
public function __construct(private Column $left, private Column $right) | ||
{ | ||
} | ||
|
||
public function __toString() | ||
{ | ||
return $this->left . ' = ' . $this->right; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace QueryBuilder; | ||
|
||
class Query | ||
{ | ||
const INDENT = " "; | ||
|
||
const FINAL_SEMI_COLON = ";" . PHP_EOL; | ||
|
||
private $select; | ||
private $from; | ||
private $where; | ||
|
||
public function __construct(Select $select, From $from, Where $where) | ||
{ | ||
$this->select = $select; | ||
$this->from = $from; | ||
$this->where = $where; | ||
} | ||
|
||
public function __toString() | ||
{ | ||
$parts = [ | ||
$this->select, | ||
$this->from, | ||
"WHERE " . $this->where, | ||
Query::FINAL_SEMI_COLON, | ||
]; | ||
|
||
return implode(PHP_EOL, $parts); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
namespace QueryBuilder; | ||
|
||
class Select | ||
{ | ||
private array $columns; | ||
|
||
public function __construct(Column ...$columns) | ||
{ | ||
$this->columns = $columns; | ||
} | ||
|
||
public function add(Column $column){ | ||
$this->columns[] = $column; | ||
return $this; | ||
} | ||
|
||
public function __toString() | ||
{ | ||
$select = implode("," . PHP_EOL . Query::INDENT, $this->columns); | ||
return "SELECT" . PHP_EOL . Query::INDENT . $select; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
namespace QueryBuilder; | ||
|
||
class Sum extends Column | ||
{ | ||
public function __construct( | ||
private string $expression, | ||
private ?string $alias = null | ||
) { | ||
$this->expression = 'SUM(' . $this->expression . ')'; | ||
} | ||
|
||
public function __toString() | ||
{ | ||
if ($this->alias) { | ||
return $this->expression . ' AS ' . $this->alias; | ||
} | ||
return $this->expression; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
namespace QueryBuilder; | ||
|
||
class Table | ||
{ | ||
public function __construct(protected string $name, private ?string $alias = null) | ||
{ | ||
} | ||
|
||
public function from() { | ||
return new From($this->alias ? $this->name . ' ' . $this->alias : $this->name); | ||
} | ||
|
||
public function column(string $expression, ?string $alias = null) | ||
{ | ||
$table = $this->alias ?? $this->name; | ||
return new Column($table . '.' . $expression, $alias); | ||
} | ||
|
||
public function sum(string $expression, ?string $as = null) | ||
{ | ||
$table = $this->alias ?? $this->name; | ||
return new Sum($table . '.' . $expression, $as); | ||
} | ||
|
||
public function __toString() | ||
{ | ||
return $this->alias ?? $this->name; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace QueryBuilder\Tests; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use QueryBuilder\From; | ||
use QueryBuilder\Join\Equals; | ||
use QueryBuilder\Query; | ||
use QueryBuilder\Select; | ||
use QueryBuilder\Table; | ||
use QueryBuilder\Where; | ||
|
||
class QueryTest extends TestCase | ||
{ | ||
public function testQuery() | ||
{ | ||
$customers = new class('customers') extends Table { | ||
public function name() { | ||
return $this->column('name'); | ||
} | ||
public function id() { | ||
return $this->column('id'); | ||
} | ||
public function departement() { | ||
return $this->column('departement'); | ||
} | ||
public function departementShouldBe(int $departement) { | ||
return new Where\Equals($this->departement(), (string) $departement); | ||
} | ||
|
||
public function joins(Table $orders){ | ||
return $orders->from()->join($this->name, new Equals($orders->customerId(), $this->id())); | ||
} | ||
}; | ||
|
||
$orders = new class('orders') extends Table { | ||
public function customerId() { | ||
return $this->column('customer_id'); | ||
} | ||
public function id() { | ||
return $this->column('id'); | ||
} | ||
public function valid() { | ||
return $this->column('valid'); | ||
} | ||
public function shouldBeValid() { | ||
return new Where\Equals($this->column('valid'), 'TRUE'); | ||
} | ||
public function total() { | ||
return $this->sum('price',as: 'total'); | ||
} | ||
}; | ||
|
||
$customerOrders = new class($orders, $customers) extends From { | ||
public function __construct($orders, $customers) | ||
{ | ||
parent::__construct('orders'); | ||
$this->join('customers', new Equals($orders->customerId(), $customers->id())); | ||
} | ||
}; | ||
|
||
$select = new Select( | ||
$orders->total(), | ||
$customers->name(), | ||
); | ||
|
||
$validDepartements = Where::atLeastOne( | ||
$customers->departementShouldBe(14), | ||
$customers->departementShouldBe(15), | ||
); | ||
$where = Where::everyOnes( | ||
$orders->shouldBeValid(), | ||
$validDepartements, | ||
); | ||
|
||
$query = new Query($select, $customerOrders, $where); | ||
|
||
$sql = <<<SQL | ||
SELECT | ||
SUM(orders.price) AS total, | ||
customers.name | ||
FROM orders | ||
JOIN customers ON orders.customer_id = customers.id | ||
WHERE orders.valid = TRUE AND (customers.departement = 14 OR customers.departement = 15) | ||
; | ||
SQL; | ||
self::assertSame($sql, (string) $query); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
|
||
namespace QueryBuilder; | ||
|
||
use QueryBuilder\Where\Ensemble; | ||
|
||
class Where | ||
{ | ||
public function __construct(private string $expression) | ||
{ | ||
} | ||
|
||
public static function atLeastOne(self ...$wheres): self { | ||
foreach ($wheres as &$where) { | ||
if ($where instanceof Ensemble) { | ||
$where = '(' . $where . ')'; | ||
} | ||
} | ||
return new Ensemble(implode(' OR ', $wheres)); | ||
} | ||
|
||
public static function everyOnes(self ...$wheres): self { | ||
foreach ($wheres as &$where) { | ||
if ($where instanceof Ensemble) { | ||
$where = '(' . $where . ')'; | ||
} | ||
} | ||
return new Ensemble(implode(' AND ', $wheres)); | ||
} | ||
|
||
public function __toString(): string | ||
{ | ||
return $this->expression; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
namespace QueryBuilder\Where; | ||
|
||
use QueryBuilder\Column; | ||
use QueryBuilder\Where; | ||
|
||
class Ensemble extends Where | ||
{ | ||
public function __construct(private string $expression) | ||
{ | ||
} | ||
|
||
public function __toString(): string | ||
{ | ||
return $this->expression; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
|
||
namespace QueryBuilder\Where; | ||
|
||
use QueryBuilder\Column; | ||
use QueryBuilder\Where; | ||
|
||
class Equals extends Where | ||
{ | ||
public function __construct(private Column $left, private string $right) | ||
{ | ||
} | ||
|
||
public function __toString(): string | ||
{ | ||
return $this->left . ' = ' . $this->right; | ||
} | ||
} | ||
|