Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@
['name' => 'ApiTables#update', 'url' => '/api/2/tables/{id}', 'verb' => 'PUT'],
['name' => 'ApiTables#destroy', 'url' => '/api/2/tables/{id}', 'verb' => 'DELETE'],
['name' => 'ApiTables#transfer', 'url' => '/api/2/tables/{id}/transfer', 'verb' => 'PUT'],
['name' => 'ApiTables#schemeDiff', 'url' => '/api/2/tables/{id}/scheme/diff', 'verb' => 'POST'],
['name' => 'ApiTables#applyScheme', 'url' => '/api/2/tables/{id}/scheme', 'verb' => 'PUT'],

['name' => 'ApiColumns#index', 'url' => '/api/2/columns/{nodeType}/{nodeId}', 'verb' => 'GET'],
['name' => 'ApiColumns#show', 'url' => '/api/2/columns/{id}', 'verb' => 'GET'],
Expand Down
74 changes: 74 additions & 0 deletions lib/Controller/ApiTablesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Exception;
use OCA\Tables\AppInfo\Application;
use OCA\Tables\Dto\Column as ColumnDto;
use OCA\Tables\Errors\BadRequestError;
use OCA\Tables\Errors\InternalError;
use OCA\Tables\Errors\NotFoundError;
use OCA\Tables\Errors\PermissionError;
Expand All @@ -18,12 +19,15 @@
use OCA\Tables\Model\SortRuleSet;
use OCA\Tables\Model\ViewUpdateInput;
use OCA\Tables\ResponseDefinitions;
use OCA\Tables\Service\ApplySchemeService;
use OCA\Tables\Service\ColumnService;
use OCA\Tables\Service\StructureDiffService;
use OCA\Tables\Service\TableService;
use OCA\Tables\Service\ViewService;
use OCP\App\IAppManager;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\UserRateLimit;
use OCP\AppFramework\Http\DataResponse;
use OCP\IDBConnection;
use OCP\IL10N;
Expand All @@ -41,6 +45,8 @@ class ApiTablesController extends AOCSController {
private ViewService $viewService;
private IAppManager $appManager;
private IDBConnection $db;
private StructureDiffService $structureDiffService;
private ApplySchemeService $applySchemeService;

public function __construct(
IRequest $request,
Expand All @@ -51,13 +57,17 @@ public function __construct(
IL10N $n,
IAppManager $appManager,
IDBConnection $db,
StructureDiffService $structureDiffService,
ApplySchemeService $applySchemeService,
string $userId) {
parent::__construct($request, $logger, $n, $userId);
$this->service = $service;
$this->columnService = $columnService;
$this->appManager = $appManager;
$this->viewService = $viewService;
$this->db = $db;
$this->structureDiffService = $structureDiffService;
$this->applySchemeService = $applySchemeService;
}

/**
Expand Down Expand Up @@ -124,6 +134,70 @@ public function showScheme(int $id): DataResponse {
}
}

/**
* [api v2] Compute a structural diff between the current table state and an incoming scheme
*
* @param int $id Table ID
* @param array $scheme Incoming scheme JSON
* @return DataResponse<Http::STATUS_OK, array, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_FORBIDDEN|Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
*
* 200: Diff returned
* 400: Bad request
* 403: No permissions
* 404: Not found
*/
#[NoAdminRequired]
#[RequirePermission(permission: Application::PERMISSION_MANAGE, type: Application::NODE_TYPE_TABLE, idParam: 'id')]
#[UserRateLimit(limit: 20, period: 60)]
public function schemeDiff(int $id, array $scheme = []): DataResponse {
try {
return new DataResponse($this->structureDiffService->computeDiff($id, $scheme));
} catch (BadRequestError $e) {
return $this->handleBadRequestError($e);
} catch (PermissionError $e) {
return $this->handlePermissionError($e);
} catch (InternalError $e) {
return $this->handleError($e);
} catch (NotFoundError $e) {
return $this->handleNotFoundError($e);
}
}

/**
* [api v2] Apply selected structural changes from a scheme to an existing table atomically
*
* @param int $id Table ID
* @param array $scheme Incoming scheme JSON
* @param array $selection Selection payload describing which changes to apply
* @return DataResponse<Http::STATUS_OK, array, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_FORBIDDEN|Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
*
* 200: Updated scheme returned
* 400: Bad request
* 403: No permissions
* 404: Not found
* 500: Internal error (failedStep included in response body)
*/
#[NoAdminRequired]
#[RequirePermission(permission: Application::PERMISSION_MANAGE, type: Application::NODE_TYPE_TABLE, idParam: 'id')]
#[UserRateLimit(limit: 20, period: 60)]
public function applyScheme(int $id, array $scheme = [], array $selection = []): DataResponse {
try {
return new DataResponse($this->applySchemeService->apply($id, $scheme, $selection));
} catch (BadRequestError $e) {
return $this->handleBadRequestError($e);
} catch (PermissionError $e) {
return $this->handlePermissionError($e);
} catch (InternalError $e) {
$this->logger->error('Failed to apply scheme: ' . $e->getMessage(), ['exception' => $e]);
return new DataResponse(
['message' => $e->getMessage(), 'failedStep' => $e->getMessage()],
Http::STATUS_INTERNAL_SERVER_ERROR,
);
} catch (NotFoundError $e) {
return $this->handleNotFoundError($e);
}
}

/**
* creates table from scheme
*
Expand Down
2 changes: 1 addition & 1 deletion lib/Db/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ public function jsonSerialize(): array {
}

public function getCustomSettingsArray(): array {
return json_decode($this->customSettings, true) ?: [];
return json_decode($this->customSettings ?? '{}', true) ?: [];
}

/**
Expand Down
Loading
Loading