Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
79 changes: 54 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,80 @@ 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)");
}

$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 +115,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