Skip to content

Commit

Permalink
feat(Rows): implement server side sorting
Browse files Browse the repository at this point in the history
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
  • Loading branch information
blizzz committed Dec 19, 2024
1 parent 2ad960c commit 6c19794
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 10 deletions.
46 changes: 40 additions & 6 deletions lib/Db/Row2Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,7 @@ public function findAll(array $tableColumns, array $columns, int $tableId, ?int

$wantedRowIdsArray = $this->getWantedRowIds($userId, $tableId, $filter, $limit, $offset);

// TODO add sorting

return $this->getRows($wantedRowIdsArray, $columnIdsArray);
return $this->getRows($wantedRowIdsArray, $columnIdsArray, $sort ?? []);
}

/**
Expand All @@ -186,7 +184,7 @@ public function findAll(array $tableColumns, array $columns, int $tableId, ?int
* @return Row2[]
* @throws InternalError
*/
private function getRows(array $rowIds, array $columnIds): array {
private function getRows(array $rowIds, array $columnIds, array $sort = []): array {
$qb = $this->db->getQueryBuilder();

$qbSqlForColumnTypes = null;
Expand Down Expand Up @@ -224,14 +222,16 @@ private function getRows(array $rowIds, array $columnIds): array {
->innerJoin('t1', 'tables_row_sleeves', 'rs', 'rs.id = t1.row_id');

try {
$result = $this->db->executeQuery($qb->getSQL(), $qb->getParameters(), $qb->getParameterTypes());
$result = $qb->executeQuery();
} catch (Exception $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage(), );
}

try {
$sleeves = $this->rowSleeveMapper->findMultiple($rowIds);
$sleeves = $this->rowSleeveMapper->findMultiple($rowIds, function (IQueryBuilder $qb) use ($sort) {
$this->addSortQueryForMultipleSleeveFinder($qb, $sort);
});
} catch (Exception $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
throw new InternalError(get_class($this) . ' - ' . __FUNCTION__ . ': ' . $e->getMessage());
Expand Down Expand Up @@ -263,6 +263,40 @@ private function addFilterToQuery(IQueryBuilder &$qb, array $filters, string $us
}
}

/**
* This method is passed to RowSleeveMapper::findMultiple() when the rows need sorting. The RowSleeveMapper does not have
* knowledge about the column information, as they reside in this class, and the mapper is called from here.
*
* @throws InternalError
*/
private function addSortQueryForMultipleSleeveFinder(IQueryBuilder $qb, array $sort): void {
$i = 1;
foreach (array_reverse($sort) as $sortData) {
if (!isset($this->columns[$sortData['columnId']]) && !isset($this->allColumns[$sortData['columnId']]) && $sortData['columnId'] > 0) {
throw new InternalError('No column found to build filter with for id ' . $sortData['columnId']);
}

// if is normal column
if ($sortData['columnId'] >= 0) {
$column = $this->columns[$sortData['columnId']] ?? $this->allColumns[$sortData['columnId']];
$valueTable = 'tables_row_cells_' . $column->getType();
$alias = 'sort' . $i;
$qb->leftJoin('sleeves', $valueTable, $alias,
$qb->expr()->andX(
$qb->expr()->eq('sleeves.id', $alias . '.row_id'),
$qb->expr()->eq($alias . '.column_id', $qb->createNamedParameter($sortData['columnId']))
)
);
$qb->orderBy($alias . '.value', $sortData['mode']);
} elseif ($sortData['columnId'] < 0) {
// TODO: implement this
// cf. $qb->createFunction($this->getMetaFilterExpression($qb, $sortData['columnId'], $filter['operator'], $filter['value'])->getSQL())
}
$i++;
}
}


private function replacePlaceholderValues(array &$filters, string $userId): void {
foreach ($filters as &$filterGroup) {
foreach ($filterGroup as &$filter) {
Expand Down
12 changes: 8 additions & 4 deletions lib/Db/RowSleeveMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ public function find(int $id): RowSleeve {

/**
* @param int[] $ids
* @param ?callable $sorter an optional callback function that accepts the IQueryBuilder as parameter
* @return RowSleeve[]
* @throws Exception
*/
public function findMultiple(array $ids): array {
public function findMultiple(array $ids, ?callable $sorter = null): array {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->table)
->where($qb->expr()->in('id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)));
$qb->select('sleeves.id', 'sleeves.table_id', 'sleeves.created_by', 'sleeves.created_at', 'sleeves.last_edit_by', 'sleeves.last_edit_at')
->from($this->table, 'sleeves')
->where($qb->expr()->in('sleeves.id', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)));
if ($sorter !== null) {
$sorter($qb);
}
return $this->findEntities($qb);
}

Expand Down

0 comments on commit 6c19794

Please sign in to comment.