Skip to content
Open
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
3 changes: 3 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use OCA\Tables\Search\SearchTablesProvider;
use OCA\Tables\Service\Support\AuditLogServiceInterface;
use OCA\Tables\Service\Support\DefaultAuditLogService;
use OCA\Tables\TablesMigrator;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
Expand Down Expand Up @@ -94,6 +95,8 @@ public function register(IRegistrationContext $context): void {

$context->registerMiddleware(PermissionMiddleware::class);
$context->registerMiddleware(ShareControlMiddleware::class);

$context->registerUserMigrator(TablesMigrator::class);
}

public function boot(IBootContext $context): void {
Expand Down
18 changes: 18 additions & 0 deletions lib/Db/ColumnMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,22 @@ public function preloadColumns(array $columns, ?array $filters = null, ?array $s
private function getCacheKey(int $id): string {
return 'column_' . $id;
}

/**
* @param int[] $tableIds
*
* @return Column[]
*/
public function findAllByTableIds(array $tableIds): array {
if (empty($tableIds)) {
return [];
}

$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->table)
->where($qb->expr()->in('table_id', $qb->createNamedParameter($tableIds, IQueryBuilder::PARAM_INT_ARRAY)));

return $this->findEntities($qb);
}
}
31 changes: 31 additions & 0 deletions lib/Db/RowCellBulkFetchTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Tables\Db;

use OCP\DB\QueryBuilder\IQueryBuilder;

trait RowCellBulkFetchTrait {
/**
* @param int[] $rowIds
* @param int[] $columnIds
*
* @return array
*/
public function findAllByRowIdsAndColumnIds(array $rowIds, array $columnIds): array {
if (empty($rowIds) || empty($columnIds)) {
return [];
}
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->table)
->where($qb->expr()->in('row_id', $qb->createNamedParameter($rowIds, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->in('column_id', $qb->createNamedParameter($columnIds, IQueryBuilder::PARAM_INT_ARRAY)));

return $this->findEntities($qb);
}
}
2 changes: 2 additions & 0 deletions lib/Db/RowCellDatetimeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

/** @template-extends RowCellMapperSuper<RowCellDatetime, string, string> */
class RowCellDatetimeMapper extends RowCellMapperSuper {
use RowCellBulkFetchTrait;

protected string $table = 'tables_row_cells_datetime';

public function __construct(IDBConnection $db) {
Expand Down
2 changes: 2 additions & 0 deletions lib/Db/RowCellNumberMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

/** @template-extends RowCellMapperSuper<RowCellNumber, int|float|null, int|float|null> */
class RowCellNumberMapper extends RowCellMapperSuper {
use RowCellBulkFetchTrait;

protected string $table = 'tables_row_cells_number';

public function __construct(IDBConnection $db) {
Expand Down
2 changes: 2 additions & 0 deletions lib/Db/RowCellSelectionMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* @template-extends RowCellMapperSuper<RowCellSelection, string, string|array>
*/
class RowCellSelectionMapper extends RowCellMapperSuper {
use RowCellBulkFetchTrait;

protected string $table = 'tables_row_cells_selection';

public function __construct(IDBConnection $db) {
Expand Down
2 changes: 2 additions & 0 deletions lib/Db/RowCellTextMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

/** @template-extends RowCellMapperSuper<RowCellText, string, string> */
class RowCellTextMapper extends RowCellMapperSuper {
use RowCellBulkFetchTrait;

protected string $table = 'tables_row_cells_text';

public function __construct(IDBConnection $db) {
Expand Down
2 changes: 2 additions & 0 deletions lib/Db/RowCellUsergroupMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

/** @template-extends RowCellMapperSuper<RowCellUsergroup, array, array> */
class RowCellUsergroupMapper extends RowCellMapperSuper {
use RowCellBulkFetchTrait;

protected string $table = 'tables_row_cells_usergroup';

public function __construct(
Expand Down
16 changes: 16 additions & 0 deletions lib/Db/RowSleeveMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,20 @@ public function countRows(int $tableId): int {
return 0;
}
}

/**
* @param int[] $tableIds
*
* @return RowSleeve[]
*/
public function findAllByTableIds(array $tableIds): array {
if (empty($tableIds)) {
return [];
}
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->table)
->where($qb->expr()->in('table_id', $qb->createNamedParameter($tableIds, IQueryBuilder::PARAM_INT_ARRAY)));
return $this->findEntities($qb);
}
}
33 changes: 33 additions & 0 deletions lib/Db/ShareMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,37 @@ public function deleteByNode(int $nodeId, string $nodeType):void {
->andWhere($qb->expr()->eq('node_type', $qb->createNamedParameter($nodeType, IQueryBuilder::PARAM_STR)))
->executeStatement();
}

/**
* @param int[] $tableIds
* @param int[] $contextIds
*
* @return Share[]
*/
// add better function name
public function findByNodeIdsAndTypes(array $tableIds, array $contextIds): array {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->table);

$orX = $qb->expr()->orX();
if (!empty($tableIds)) {
$orX->add(
$qb->expr()->andX(
$qb->expr()->eq('node_type', $qb->createNamedParameter('table', IQueryBuilder::PARAM_STR)),
$qb->expr()->in('node_id', $qb->createNamedParameter($tableIds, IQueryBuilder::PARAM_INT_ARRAY))
)
);
}
if (!empty($contextIds)) {
$orX->add(
$qb->expr()->andX(
$qb->expr()->eq('node_type', $qb->createNamedParameter('context', IQueryBuilder::PARAM_STR)),
$qb->expr()->in('node_id', $qb->createNamedParameter($contextIds, IQueryBuilder::PARAM_INT_ARRAY))
)
);
}
$qb->where($orX);
return $this->findEntities($qb);
}
}
4 changes: 4 additions & 0 deletions lib/Db/TableMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,8 @@ public function insert(Entity $entity): Table {
$this->cache[(string)$entity->getId()] = $entity;
return $entity;
}

public function getDbConnection() {
return $this->db;
}
}
51 changes: 51 additions & 0 deletions lib/Service/ColumnService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Exception;
use OCA\Tables\Db\Column;
use OCA\Tables\Db\ColumnMapper;
use OCA\Tables\Db\Table;
use OCA\Tables\Db\TableMapper;
use OCA\Tables\Db\View;
use OCA\Tables\Dto\Column as ColumnDto;
Expand Down Expand Up @@ -558,4 +559,54 @@ private function enhanceColumns(?array $columns, ?View $view = null): array {
}
return $columns;
}

/**
* @param Table $table
* @param array $column
*
* @return Column
*
* @throws InternalError
*/
public function importColumn(Table $table, array $column): Column {
$item = new Column();
$item->setTableId($table->getId());
$item->setTitle($column['title']);
$item->setCreatedBy($table->getOwnership());
$item->setCreatedAt($column['createdAt']);
$item->setLastEditBy($table->getOwnership());
$item->setLastEditAt($column['lastEditAt']);
$item->setType($column['type']);
$item->setSubtype($column['subtype']);
$item->setMandatory($column['mandatory']);
$item->setDescription($column['description']);
$item->setNumberDefault($column['numberDefault']);
$item->setNumberMin($column['numberMin']);
$item->setNumberMax($column['numberMax']);
$item->setNumberDecimals($column['numberDecimals']);
$item->setNumberPrefix($column['numberPrefix']);
$item->setNumberSuffix($column['numberSuffix']);
$item->setTextDefault($column['textDefault']);
$item->setTextAllowedPattern($column['textAllowedPattern']);
$item->setTextMaxLength($column['textMaxLength']);
$item->setTextUnique($column['textUnique']);
$item->setSelectionOptions(json_encode($column['selectionOptions']));
$item->setSelectionDefault($column['selectionDefault']);
$item->setDatetimeDefault($column['datetimeDefault']);
$item->setUsergroupDefault(json_encode($column['usergroupDefault']));
$item->setUsergroupMultipleItems($column['usergroupMultipleItems']);
$item->setUsergroupSelectUsers($column['usergroupSelectUsers']);
$item->setUsergroupSelectGroups($column['usergroupSelectGroups']);
$item->setUsergroupSelectTeams($column['usergroupSelectTeams']);
$item->setShowUserStatus($column['showUserStatus']);
$item->setCustomSettings(json_encode($column['customSettings']));

try {
$newColumn = $this->mapper->insert($item);
} catch (\Exception $e) {
$this->logger->error('importColumn insert error: ' . $e->getMessage());
throw new InternalError('importColumn insert error: ' . $e->getMessage());
}
return $newColumn;
}
}
76 changes: 76 additions & 0 deletions lib/Service/ContextService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use OCA\Tables\Db\PageContent;
use OCA\Tables\Db\PageContentMapper;
use OCA\Tables\Db\PageMapper;
use OCA\Tables\Db\Table;
use OCA\Tables\Errors\BadRequestError;
use OCA\Tables\Errors\InternalError;
use OCA\Tables\Errors\NotFoundError;
Expand Down Expand Up @@ -508,4 +509,79 @@ protected function insertNodesFromArray(Context $context, array $nodes): void {
}
$context->setNodes($addedNodes);
}

/**
* @param Table $table
* @param array $context
* @param int $tableOldId
*
* @return Context|null
*
* @throws \Exception
*/
public function importContext(Table $table, array $context, int $tableOldId): ?Context {
// checking if any node in $context['nodes'] matches the old table id
$hasMatchingNode = false;
if (!empty($context['nodes'])) {
foreach ($context['nodes'] as $nodeArr) {
if (($nodeArr['node_id'] ?? null) == $tableOldId) {
$hasMatchingNode = true;
break;
}
}
}

if (!$hasMatchingNode) {
return null;
}

$newContext = new Context();
$newContext->setName($context['name'] ?? '');
$newContext->setIcon($context['iconName'] ?? '');
$newContext->setDescription($context['description'] ?? '');
$newContext->setOwnerId($table->getOwnership() ?? '');
$newContext->setOwnerType($context['ownerType'] ?? 0);
$this->contextMapper->insert($newContext);

// insert nodes
$nodeRelMap = [];
if (!empty($context['nodes'])) {
foreach ($context['nodes'] as $nodeArr) {
$contextNodeRel = new ContextNodeRelation();
$contextNodeRel->setContextId($newContext->getId());
$contextNodeRel->setNodeId($table->getId());
$contextNodeRel->setNodeType($nodeArr['node_type'] ?? $nodeArr['nodeType'] ?? 0);
$contextNodeRel->setPermissions($nodeArr['permissions'] ?? 0);
$contextNodeRel = $this->contextNodeRelMapper->insert($contextNodeRel);
$nodeRelMap[$nodeArr['id'] ?? null] = $contextNodeRel;
}
}

// insert pages
$pageMap = [];
if (!empty($context['pages'])) {
foreach ($context['pages'] as $pageArr) {
$page = new Page();
$page->setContextId($newContext->getId());
$page->setPageType($pageArr['page_type'] ?? $pageArr['pageType'] ?? '');
$page = $this->pageMapper->insert($page);
$pageMap[$pageArr['id'] ?? null] = $page;

// insert page conten
if (!empty($pageArr['content'])) {
foreach ($pageArr['content'] as $contentArr) {
$pageContent = new PageContent();
$pageContent->setPageId($page->getId());
$oldNodeRelId = $contentArr['node_rel_id'] ?? $contentArr['nodeRelId'] ?? null;
$newNodeRel = $nodeRelMap[$oldNodeRelId] ?? null;
$pageContent->setNodeRelId($newNodeRel ? $newNodeRel->getId() : null);
$pageContent->setOrder($contentArr['order'] ?? 100);
$this->pageContentMapper->insert($pageContent);
}
}
}
}

return $newContext;
}
}
43 changes: 43 additions & 0 deletions lib/Service/FavoritesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace OCA\Tables\Service;

use OCA\Tables\AppInfo\Application;
use OCA\Tables\Db\Table;
use OCA\Tables\Errors\InternalError;
use OCA\Tables\Errors\NotFoundError;
use OCA\Tables\Errors\PermissionError;
Expand Down Expand Up @@ -115,4 +116,46 @@ private function checkAccessToNode(int $nodeType, int $nodeId): void {
throw new PermissionError('Invalid node type and id');
}

/**
* @param string|null $userId
*
* @return array<int, array<string, mixed>>
*
* @throws Exception
*/
public function findAll(?string $userId = null): array {
$qb = $this->connection->getQueryBuilder();
$qb->select('*')
->from('tables_favorites')
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)));

$result = $qb->executeQuery();
$rows = [];
while ($row = $result->fetch()) {
$rows[] = $row;
}
return $rows;
}

/**
* @param int $nodeType
* @param Table $table
*
* @throws InternalError
* @throws Exception
*/
public function importFavorite(int $nodeType, Table $table): void {
$this->checkValidNodeType($nodeType);

$qb = $this->connection->getQueryBuilder();
$qb->insert('tables_favorites')
->values([
'user_id' => $qb->createNamedParameter($table->getOwnership()),
'node_type' => $qb->createNamedParameter($nodeType),
'node_id' => $qb->createNamedParameter($table->getId()),
]);
$qb->executeStatement();
$this->cache->set($nodeType . '_' . $table->getId(), true);
}

}
Loading
Loading