Skip to content

Commit

Permalink
Merge pull request #36 from ConductionNL/development
Browse files Browse the repository at this point in the history
Fixes on filters
  • Loading branch information
rjzondervan authored Oct 21, 2024
2 parents 5dcfdd6 + 3b15380 commit 0c51976
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 33 deletions.
5 changes: 3 additions & 2 deletions lib/Db/ObjectEntityMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public function updateFromArray(int $id, array $object): ObjectEntity
return $this->update($obj);
}

public function getFacets(array $filters = [])
public function getFacets(array $filters = [], ?string $search = null)
{
if(key_exists(key: 'register', array: $filters) === true) {
$register = $filters['register'];
Expand Down Expand Up @@ -221,7 +221,8 @@ public function getFacets(array $filters = [])
fields: $fields,
register: $register,
schema: $schema,
filters: $filters
filters: $filters,
search: $search
);
}
}
43 changes: 42 additions & 1 deletion lib/Service/IDatabaseJsonService.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,47 @@

interface IDatabaseJsonService
{
/**
* Filters the JSON objects in the objects column based upon given filters.
*
* @param IQueryBuilder $builder The query builder, make sure this matches the database platform used.
* @param array $filters The filters to filter on.
*
* @return IQueryBuilder The updated query builder.
*/
public function filterJson(IQueryBuilder $builder, array $filters): IQueryBuilder;
public function getAggregations(IQueryBuilder $builder, array $fields, int $register, int $schema, array $filters = []): array;

/**
* Searches in the JSON bojects in the objects column for given string.
*
* @param IQueryBuilder $builder The query builder, make sure this matches the database platform used.
* @param string $search The search string to search for.
*
* @return IQueryBuilder The updated query builder.
*/
public function searchJson(IQueryBuilder $builder, string $search): IQueryBuilder;

/**
* Sorts search results on json fields.
*
* @param IQueryBuilder $builder The query builder, make sure this matches the database platform used.
* @param array $order The fields to order on, and the direction to order with.
*
* @return IQueryBuilder The updated query builder.
*/
public function orderJson(IQueryBuilder $builder, array $order): IQueryBuilder;

/**
* Generates aggregations (facets) for given fields combined with given filters.
*
* @param IQueryBuilder $builder The query builder, make sure this matches the database platform used.
* @param array $fields The fields to generate aggregations for.
* @param int $register The register id to filter.
* @param int $schema The schema id to filter.
* @param array $filters The filters applied to the request.
* @param string|null $search The search string supplied by the request
*
* @return array The resulting aggregations
*/
public function getAggregations(IQueryBuilder $builder, array $fields, int $register, int $schema, array $filters = [], ?string $search = null): array;
}
80 changes: 55 additions & 25 deletions lib/Service/MySQLJsonService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

class MySQLJsonService implements IDatabaseJsonService
{
function orderJson(IQueryBuilder $builder, array $order = []): IQueryBuilder
/**
* @inheritDoc
*/
public function orderJson(IQueryBuilder $builder, array $order = []): IQueryBuilder
{

foreach($order as $item=>$direction) {
Expand All @@ -20,55 +23,81 @@ function orderJson(IQueryBuilder $builder, array $order = []): IQueryBuilder
return $builder;
}

function searchJson(IQueryBuilder $builder, ?string $search = null): IQueryBuilder
/**
* @inheritDoc
*/
public function searchJson(IQueryBuilder $builder, ?string $search = null): IQueryBuilder
{
if($search !== null) {
if ($search !== null) {
$builder->createNamedParameter(value: "%$search%", placeHolder: ':search');
$builder->andWhere("JSON_SEARCH(object, 'one', :search) IS NOT NULL");
$builder->andWhere("JSON_SEARCH(LOWER(object), 'one', LOWER(:search)) IS NOT NULL");
}

return $builder;
}

function filterJson(IQueryBuilder $builder, array $filters): IQueryBuilder
/**
* @inheritDoc
*/
private function jsonFilterArray(IQueryBuilder $builder, string $filter, array $values): IQueryBuilder
{
foreach ($values as $key=>$value) {
switch ($key) {
case 'after':
$builder->createNamedParameter(value: $value, type: IQueryBuilder::PARAM_STR, placeHolder: ":value{$filter}after");
$builder
->andWhere("json_unquote(json_extract(object, :path$filter)) >= (:value{$filter}after)");
break;
case 'before':
$builder->createNamedParameter(value: $value, type: IQueryBuilder::PARAM_STR, placeHolder: ":value${filter}before");
$builder
->andWhere("json_unquote(json_extract(object, :path$filter)) <= (:value{$filter}before)");
break;
default:
$builder->createNamedParameter(value: $value, type: IQueryBuilder::PARAM_STR_ARRAY, placeHolder: ":value$filter");
$builder
->andWhere("json_unquote(json_extract(object, :path$filter)) IN (:value$filter)");
break;

}
}

return $builder;
}

/**
* @inheritDoc
*/
public function filterJson(IQueryBuilder $builder, array $filters): IQueryBuilder
{
unset($filters['register'], $filters['schema'], $filters['updated'], $filters['created'], $filters['_queries']);

foreach($filters as $filter=>$value) {

$builder->createNamedParameter(value: "$.$filter", placeHolder: ":path$filter");

if(is_array($value) === true) {
switch(array_keys($value)[0]) {
case 'after':
$builder->createNamedParameter(value: $value, type: IQueryBuilder::PARAM_STR_ARRAY, placeHolder: ":value$filter");
$builder
->andWhere("json_unquote(json_extract(object, :path$filter)) >= (:value$filter)");
break;
case 'before':
$builder->createNamedParameter(value: $value, type: IQueryBuilder::PARAM_STR_ARRAY, placeHolder: ":value$filter");
$builder
->andWhere("json_unquote(json_extract(object, :path$filter)) <= (:value$filter)");
break;
default:
$builder->createNamedParameter(value: $value, type: IQueryBuilder::PARAM_STR_ARRAY, placeHolder: ":value$filter");
$builder
->andWhere("json_unquote(json_extract(object, :path$filter)) IN (:value$filter)");
break;
}
if(is_array($value) === true && array_is_list($value) === false) {
$builder = $this->jsonFilterArray(builder: $builder, filter: $filter, values: $value);
continue;
} else if (is_array($value) === true) {
$builder->createNamedParameter(value: $value, type: IQueryBuilder::PARAM_STR_ARRAY, placeHolder: ":value$filter");
$builder
->andWhere("json_unquote(json_extract(object, :path$filter)) IN (:value$filter)");
continue;
}

$builder->createNamedParameter(value: $value, placeHolder: ":value$filter");
$builder
->andWhere("json_extract(object, :path$filter) = :value$filter OR json_contains(object, json_quote(:value$filter), :path$filter)");
}
// var_dump($builder->getSQL());

return $builder;
}

public function getAggregations(IQueryBuilder $builder, array $fields, int $register, int $schema, array $filters = []): array
/**
* @inheritDoc
*/
public function getAggregations(IQueryBuilder $builder, array $fields, int $register, int $schema, array $filters = [], ?string $search = null): array
{
$facets = [];

Expand All @@ -87,6 +116,7 @@ public function getAggregations(IQueryBuilder $builder, array $fields, int $regi
->groupBy('_id');

$builder = $this->filterJson($builder, $filters);
$builder = $this->searchJson($builder, $search);

$result = $builder->executeQuery();
$facets[$field] = $result->fetchAll();
Expand Down
10 changes: 5 additions & 5 deletions lib/Service/ObjectService.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function createFromArray(array $object) {

public function updateFromArray(string $id, array $object, bool $updatedObject) {
$object['id'] = $id;

return $this->saveObject(
register: $this->getRegister(),
schema: $this->getSchema(),
Expand Down Expand Up @@ -117,15 +117,15 @@ public function findMultiple(array $ids): array
return $result;
}

public function getAggregations(array $filters): array
public function getAggregations(array $filters, ?string $search = null): array
{
$mapper = $this->getMapper(objectType: 'objectEntity');

$filters['register'] = $this->getRegister();
$filters['schema'] = $this->getSchema();

if ($mapper instanceof ObjectEntityMapper === true) {
$facets = $this->objectEntityMapper->getFacets($filters);
$facets = $this->objectEntityMapper->getFacets($filters, $search);
return $facets;
}

Expand Down Expand Up @@ -230,12 +230,12 @@ public function saveObject(int $register, int $schema, array $object): ObjectEnt
// Normal loging
//$changed = $objectEntity->getUpdatedFields();


// If the object has no uuid, create a new one
if (empty($objectEntity->getUuid())) {
$objectEntity->setUuid(Uuid::v4());
}

if($objectEntity->getId()){
$objectEntity = $this->objectEntityMapper->update($objectEntity);
$action = 'update';
Expand Down

0 comments on commit 0c51976

Please sign in to comment.