Commit 3cfd8b8a authored by François Agneray's avatar François Agneray
Browse files

Step 1 #8 (bw, gt, lt, gte, lte)

parent e49820d0
......@@ -13,10 +13,16 @@ namespace App\Action\Search;
use Psr\Log\LoggerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\DBAL\Query\Expression\CompositeExpression;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use App\Action\AbstractAction;
use App\Utils\DBALConnectionFactory;
use App\Entity\Dataset;
use App\Entity\Attribute;
use App\Search\SearchException;
use App\Search\MetaToolbox;
use App\Search\Operator\OperatorFactory;
abstract class AbstractSearchAction extends AbstractAction
{
......@@ -32,24 +38,43 @@ abstract class AbstractSearchAction extends AbstractAction
protected function addWhere(QueryBuilder $queryBuilder, Dataset $dataset, array $queryParams): void
{
if (array_key_exists('c', $queryParams)) {
$criteria = explode(';', $queryParams['c']);
$queryBuilder->where('1 = 1');
foreach ($criteria as $criterion) {
$params = explode(':', $criterion);
$attribute = $this->em->find('App\Entity\Attribute', $params[0]);
switch ($params[1]) {
case 'bw':
$values = explode('|', $params[2]);
$column = $attribute->getTableName() . '.' . $attribute->getName();
$queryBuilder->andWhere($queryBuilder->expr()->gte($column, $values[0]));
$queryBuilder->andWhere($queryBuilder->expr()->lte($column, $values[1]));
break;
default:
throw new \RuntimeException('Search type not allowed');
}
}
if (!array_key_exists('c', $queryParams)) {
throw SearchException::paramDoesNotExist('c');
}
$args = array();
$criteria = explode(';', $queryParams['c']);
foreach ($criteria as $criterion) {
$args[] = $this->getExpression($criterion, $dataset, $queryBuilder->expr());
}
$queryBuilder->where(new CompositeExpression(CompositeExpression::TYPE_AND, $args));
}
protected function getExpression(string $criterion, Dataset $dataset, ExpressionBuilder $expr)
{
$params = $this->getCriterionParams($criterion);
$attribute = $this->getCriterionAttribute($params[0], $dataset);
$column = $attribute->getTableName() . '.' . $attribute->getName();
$values = explode('|', $params[2]);
$operator = OperatorFactory::create($params[1], $expr, $column, $values);
return $operator->getExpression();
}
protected function getCriterionParams(string $criterion): array
{
$params = explode(':', $criterion);
$numberOfParams = count($params);
if ($numberOfParams != 3) {
throw SearchException::numberOfCriterionParams($numberOfParams, $criterion);
}
return $params;
}
protected function getCriterionAttribute(int $id, Dataset $dataset): Attribute
{
if (!MetaToolbox::checkOneAttributeId($dataset, $id)) {
throw SearchException::attributeNotFound($id, $dataset->getLabel());
}
return MetaToolbox::getAttributeById($dataset, $id);
}
}
......@@ -46,8 +46,6 @@ final class SearchDataAction extends AbstractSearchAction
$this->addOrder($queryBuilder, $request->getQueryParams());
$this->addLimit($queryBuilder, $request->getQueryParams());
// var_dump($queryBuilder->__toString());
$stmt = $queryBuilder->execute();
$result = $stmt->fetchAll();
......@@ -91,8 +89,6 @@ final class SearchDataAction extends AbstractSearchAction
}
$queryBuilder->orderBy($attribute->getTableName() . '.' . $attribute->getName(), $aord);
}
} else {
// TODO: Chercher la clé primaire pour faire un tri par défaut
}
}
......
......@@ -37,7 +37,6 @@ final class SearchMetaAction extends AbstractSearchAction
$connection = $this->dcf->create($database);
$queryBuilder = $connection->createQueryBuilder();
// $this->addSelect($queryBuilder, $dataset, $request->getQueryParams());
$queryBuilder->select('COUNT(*) as nb');
$queryBuilder->from($dataset->getTableRef());
$this->addWhere($queryBuilder, $dataset, $request->getQueryParams());
......
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search;
use App\Entity\Dataset;
use App\Entity\Attribute;
abstract class MetaToolbox
{
public static function getAttributeById(Dataset $dataset, int $id): Attribute
{
$attributes = $dataset->getAttributes();
foreach ($attributes as $attribute) {
if ($attribute->getId() === $id) {
return $attribute;
}
}
return null;
}
public static function checkOneAttributeId(Dataset $dataset, int $id): bool
{
$attributes = $dataset->getAttributes();
foreach ($attributes as $attribute) {
if ($attribute->getId() === $id) {
return true;
}
}
return false;
}
public static function checkListOfAttributesIds(Dataset $dataset, array $listOfIds): bool
{
$attributes = $dataset->getAttributes();
foreach ($attributes as $attribute) {
$id = $attribute->getId();
if (!in_array($id, $listOfIds)) {
return false;
}
}
return true;
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use Doctrine\DBAL\Query\Expression\CompositeExpression;
class Between extends Operator
{
private $value1;
private $value2;
public function __construct(ExpressionBuilder $expr, string $column, float $value1, float $value2)
{
parent::__construct($expr, $column);
$this->value1 = $value1;
$this->value2 = $value2;
}
public function getExpression()
{
$args = array();
$args[] = $this->expr->gte($this->column, $this->value1);
$args[] = $this->expr->lte($this->column, $this->value2);
return new CompositeExpression(CompositeExpression::TYPE_AND, $args);
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
class GreaterThan extends Operator
{
/**
* @var number
*/
private $value;
public function __construct(ExpressionBuilder $expr, string $column, float $value)
{
parent::__construct($expr, $column);
$this->value = $value;
}
public function getExpression() : string
{
return $this->expr->gt($this->column, $this->value);
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
class GreaterThanEqual extends Operator
{
/**
* @var number
*/
private $value;
public function __construct(ExpressionBuilder $expr, string $column, float $value)
{
parent::__construct($expr, $column);
$this->value = $value;
}
public function getExpression() : string
{
return $this->expr->gte($this->column, $this->value);
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
interface IOperator
{
public function getExpression();
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
class LessThan extends Operator
{
/**
* @var number
*/
private $value;
public function __construct(ExpressionBuilder $expr, string $column, float $value)
{
parent::__construct($expr, $column);
$this->value = $value;
}
public function getExpression() : string
{
return $this->expr->lt($this->column, $this->value);
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
class LessThanEqual extends Operator
{
/**
* @var number
*/
private $value;
public function __construct(ExpressionBuilder $expr, string $column, float $value)
{
parent::__construct($expr, $column);
$this->value = $value;
}
public function getExpression() : string
{
return $this->expr->lte($this->column, $this->value);
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
abstract class Operator implements IOperator
{
/**
* @var ExpressionBuilder
*/
protected $expr;
/**
* @var string
*/
protected $column;
public function __construct(ExpressionBuilder $expr, string $column)
{
$this->expr = $expr;
$this->column = $column;
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
use Exception;
class OperatorException extends Exception
{
/**
* @param string $operator
*
* @return \App\Search\Operator\OperatorException
*/
public static function unknownOperator($operator)
{
return new self("The given operateor '" . $operator . "' is unknown");
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search\Operator;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
class OperatorFactory
{
public static function create (string $type, ExpressionBuilder $expr, string $column, array $parameters): IOperator
{
switch ($type) {
case 'bw':
return new Between($expr, $column, (float) $parameters[0], (float) $parameters[1]);
case 'gt':
return new GreaterThan($expr, $column, (float) $parameters[0]);
case 'gte':
return new GreaterThanEqual($expr, $column, (float) $parameters[0]);
case 'lt':
return new LessThan($expr, $column, (float) $parameters[0]);
case 'lte':
return new LessThanEqual($expr, $column, (float) $parameters[0]);
default:
throw OperatorException::unknownOperator($type);
}
}
}
\ No newline at end of file
<?php declare(strict_types=1);
/*
* This file is part of ANIS SERVER API.
*
* (c) François Agneray <francois.agneray@lam.fr>
* (c) Chrystel Moreau <chrystel.moreau@lam.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Search;
use Exception;
class SearchException extends Exception
{
/**
* @param string $param
*
* @return \App\Search\SearchException
*/
public static function paramDoesNotExist($param)
{
return new self("The param '" . $param . "' does not exists in the URL");
}
public static function numberOfCriterionParams($numberOfParams, $criterion)
{
return new self("One criterion need 3 params. " . $numberOfParams .
" given for the substring " . $criterion);
}
public static function attributeNotFound(int $id, string $datasetLabel)
{
return new self("Attribute with the id " . $id . " is not found for the dataset " . $datasetLabel);
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment