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
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Share your tables and views with users and groups within your cloud.
Have a good time and manage whatever you want.
]]></description>
<version>2.0.1</version>
<version>2.0.2</version>
<licence>agpl</licence>
<author mail="florian.steffens@nextcloud.com">Florian Steffens</author>
<namespace>Tables</namespace>
Expand Down
9 changes: 9 additions & 0 deletions lib/Controller/Api1Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ public function indexViewColumns(int $viewId): DataResponse {
* @param int|null $tableId Table ID
* @param int|null $viewId View ID
* @param string $title Title
* @param string|null $technicalName Technical name of the column
* @param 'text'|'number'|'datetime'|'select'|'usergroup' $type Column main type
* @param string|null $subtype Column sub type
* @param bool $mandatory Is the column mandatory
Expand Down Expand Up @@ -863,6 +864,7 @@ public function createColumn(
?int $tableId,
?int $viewId,
string $title,
?string $technicalName,
string $type,
?string $subtype,
bool $mandatory,
Expand Down Expand Up @@ -901,6 +903,7 @@ public function createColumn(
$viewId,
new ColumnDto(
title: $title,
technicalName: $technicalName,
type: ColumnType::from($type)->value,
subtype: $subtype,
mandatory: $mandatory,
Expand Down Expand Up @@ -956,6 +959,7 @@ public function createColumn(
*
* @param int $columnId Column ID that will be updated
* @param string|null $title Title
* @param string|null $technicalName Technical name of the column
* @param string|null $subtype Column sub type
* @param bool $mandatory Is the column mandatory
* @param string|null $description Description
Expand Down Expand Up @@ -993,6 +997,7 @@ public function createColumn(
public function updateColumn(
int $columnId,
?string $title,
?string $technicalName,
?string $subtype,
?bool $mandatory,
?string $description,
Expand Down Expand Up @@ -1028,6 +1033,7 @@ public function updateColumn(
$this->userId,
new ColumnDto(
title: $title,
technicalName: $technicalName,
subtype: $subtype,
mandatory: $mandatory,
description: $description,
Expand Down Expand Up @@ -1600,6 +1606,7 @@ public function createTableShare(int $tableId, string $receiver, string $receive
*
* @param int $tableId Table ID
* @param string $title Title
* @param string|null $technicalName Technical name of the column
* @param 'text'|'number'|'datetime'|'select'|'usergroup' $type Column main type
* @param string|null $subtype Column sub type
* @param bool $mandatory Is the column mandatory
Expand Down Expand Up @@ -1641,6 +1648,7 @@ public function createTableShare(int $tableId, string $receiver, string $receive
public function createTableColumn(
int $tableId,
string $title,
?string $technicalName,
string $type,
?string $subtype,
bool $mandatory,
Expand Down Expand Up @@ -1679,6 +1687,7 @@ public function createTableColumn(
null,
new ColumnDto(
title: $title,
technicalName: $technicalName,
type: ColumnType::from($type)->value,
subtype: $subtype,
mandatory: $mandatory,
Expand Down
20 changes: 15 additions & 5 deletions lib/Controller/ApiColumnsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public function show(int $id): DataResponse {
*
* @param int $baseNodeId Context of the column creation
* @param string $title Title
* @param string|null $technicalName Technical name of the column
* @param boolean $mandatory Is mandatory
* @param 'table'|'view' $baseNodeType Context type of the column creation
* @param float|null $numberDefault Default value for new rows
Expand Down Expand Up @@ -144,7 +145,7 @@ public function show(int $id): DataResponse {
*/
#[NoAdminRequired]
#[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')]
public function createNumberColumn(int $baseNodeId, string $title, ?float $numberDefault, ?int $numberDecimals, ?string $numberPrefix, ?string $numberSuffix, ?float $numberMin, ?float $numberMax, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
public function createNumberColumn(int $baseNodeId, string $title, ?string $technicalName, ?float $numberDefault, ?int $numberDecimals, ?string $numberPrefix, ?string $numberSuffix, ?float $numberMin, ?float $numberMax, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
$tableId = $baseNodeType === 'table' ? $baseNodeId : null;
$viewId = $baseNodeType === 'view' ? $baseNodeId : null;
$column = $this->service->create(
Expand All @@ -153,6 +154,7 @@ public function createNumberColumn(int $baseNodeId, string $title, ?float $numbe
$viewId,
new ColumnDto(
title: $title,
technicalName: $technicalName,
type: ColumnType::NUMBER->value,
subtype: $subtype,
mandatory: $mandatory,
Expand All @@ -177,6 +179,7 @@ public function createNumberColumn(int $baseNodeId, string $title, ?float $numbe
*
* @param int $baseNodeId Context of the column creation
* @param string $title Title
* @param string|null $technicalName Technical name of the column
* @param string|null $textDefault Default
* @param string|null $textAllowedPattern Allowed regex pattern
* @param int|null $textMaxLength Max raw text length
Expand Down Expand Up @@ -207,7 +210,7 @@ public function createNumberColumn(int $baseNodeId, string $title, ?float $numbe
*/
#[NoAdminRequired]
#[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')]
public function createTextColumn(int $baseNodeId, string $title, ?string $textDefault, ?string $textAllowedPattern, ?int $textMaxLength, ?bool $textUnique = false, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
public function createTextColumn(int $baseNodeId, string $title, ?string $technicalName, ?string $textDefault, ?string $textAllowedPattern, ?int $textMaxLength, ?bool $textUnique = false, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
$tableId = $baseNodeType === 'table' ? $baseNodeId : null;
$viewId = $baseNodeType === 'view' ? $baseNodeId : null;
$column = $this->service->create(
Expand All @@ -216,6 +219,7 @@ public function createTextColumn(int $baseNodeId, string $title, ?string $textDe
$viewId,
new ColumnDto(
title: $title,
technicalName: $technicalName,
type: ColumnType::TEXT->value,
subtype: $subtype,
mandatory: $mandatory,
Expand All @@ -238,6 +242,7 @@ public function createTextColumn(int $baseNodeId, string $title, ?string $textDe
*
* @param int $baseNodeId Context of the column creation
* @param string $title Title
* @param string|null $technicalName Technical name of the column
* @param string $selectionOptions Json array{id: int, label: string} with
* options that can be selected, eg [{"id": 1, "label": "first"},{"id":
* 2, "label": "second"}]
Expand Down Expand Up @@ -270,7 +275,7 @@ public function createTextColumn(int $baseNodeId, string $title, ?string $textDe
*/
#[NoAdminRequired]
#[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')]
public function createSelectionColumn(int $baseNodeId, string $title, string $selectionOptions, ?string $selectionDefault, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
public function createSelectionColumn(int $baseNodeId, string $title, ?string $technicalName, string $selectionOptions, ?string $selectionDefault, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
$tableId = $baseNodeType === 'table' ? $baseNodeId : null;
$viewId = $baseNodeType === 'view' ? $baseNodeId : null;
$column = $this->service->create(
Expand All @@ -279,6 +284,7 @@ public function createSelectionColumn(int $baseNodeId, string $title, string $se
$viewId,
new ColumnDto(
title: $title,
technicalName: $technicalName,
type: ColumnType::SELECTION->value,
subtype: $subtype,
mandatory: $mandatory,
Expand All @@ -299,6 +305,7 @@ public function createSelectionColumn(int $baseNodeId, string $title, string $se
*
* @param int $baseNodeId Context of the column creation
* @param string $title Title
* @param string|null $technicalName Technical name of the column
* @param 'today'|'now'|null $datetimeDefault For a subtype 'date' you can
* set 'today'. For a main type or subtype 'time' you can set to 'now'.
*
Expand Down Expand Up @@ -328,7 +335,7 @@ public function createSelectionColumn(int $baseNodeId, string $title, string $se
*/
#[NoAdminRequired]
#[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')]
public function createDatetimeColumn(int $baseNodeId, string $title, ?string $datetimeDefault, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
public function createDatetimeColumn(int $baseNodeId, string $title, ?string $technicalName, ?string $datetimeDefault, ?string $subtype = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
$tableId = $baseNodeType === 'table' ? $baseNodeId : null;
$viewId = $baseNodeType === 'view' ? $baseNodeId : null;
$column = $this->service->create(
Expand All @@ -337,6 +344,7 @@ public function createDatetimeColumn(int $baseNodeId, string $title, ?string $da
$viewId,
new ColumnDto(
title: $title,
technicalName: $technicalName,
type: ColumnType::DATETIME->value,
subtype: $subtype,
mandatory: $mandatory,
Expand All @@ -354,6 +362,7 @@ public function createDatetimeColumn(int $baseNodeId, string $title, ?string $da
*
* @param int $baseNodeId Context of the column creation
* @param string $title Title
* @param string|null $technicalName Technical name of the column
* @param string|null $usergroupDefault Json array{id: string, type: int},
* eg [{"id": "admin", "type": 0}, {"id": "user1", "type": 0}]
* @param boolean $usergroupMultipleItems Whether you can select multiple
Expand Down Expand Up @@ -388,7 +397,7 @@ public function createDatetimeColumn(int $baseNodeId, string $title, ?string $da
*/
#[NoAdminRequired]
#[RequirePermission(permission: Application::PERMISSION_MANAGE, typeParam: 'baseNodeType', idParam: 'baseNodeId')]
public function createUsergroupColumn(int $baseNodeId, string $title, ?string $usergroupDefault, ?bool $usergroupMultipleItems = null, ?bool $usergroupSelectUsers = null, ?bool $usergroupSelectGroups = null, ?bool $usergroupSelectTeams = null, ?bool $showUserStatus = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
public function createUsergroupColumn(int $baseNodeId, string $title, ?string $technicalName, ?string $usergroupDefault, ?bool $usergroupMultipleItems = null, ?bool $usergroupSelectUsers = null, ?bool $usergroupSelectGroups = null, ?bool $usergroupSelectTeams = null, ?bool $showUserStatus = null, ?string $description = null, ?array $selectedViewIds = [], bool $mandatory = false, string $baseNodeType = 'table', array $customSettings = []): DataResponse {
$tableId = $baseNodeType === 'table' ? $baseNodeId : null;
$viewId = $baseNodeType === 'view' ? $baseNodeId : null;
$column = $this->service->create(
Expand All @@ -397,6 +406,7 @@ public function createUsergroupColumn(int $baseNodeId, string $title, ?string $u
$viewId,
new ColumnDto(
title: $title,
technicalName: $technicalName,
type: ColumnType::PEOPLE->value,
mandatory: $mandatory,
description: $description,
Expand Down
5 changes: 5 additions & 0 deletions lib/Db/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
*
* @method getTitle(): string
* @method setTitle(string $title)
* @method getTechnicalName(): string
* @method setTechnicalName(?string $technicalName)
* @method getTableId(): int
* @method setTableId(int $tableId)
* @method getCreatedBy(): string
Expand Down Expand Up @@ -115,6 +117,7 @@ class Column extends EntitySuper implements JsonSerializable {
public const META_ID_TITLE = 'id';

protected ?string $title = null;
protected ?string $technicalName = null;
protected ?int $tableId = null;
protected ?string $createdBy = null;
protected ?string $createdAt = null;
Expand Down Expand Up @@ -201,6 +204,7 @@ public static function isValidMetaTypeId(int $metaTypeId): bool {
public static function fromDto(ColumnDto $data): self {
$column = new self();
$column->setTitle($data->getTitle());
$column->setTechnicalName($data->getTechnicalName());
$column->setType($data->getType());
$column->setSubtype($data->getSubtype() ?? '');
$column->setMandatory($data->isMandatory() ?? false);
Expand Down Expand Up @@ -264,6 +268,7 @@ public function jsonSerialize(): array {
'id' => $this->id,
'tableId' => $this->tableId,
'title' => $this->title,
'technicalName' => $this->technicalName,
'createdBy' => $this->createdBy,
'createdByDisplayName' => $this->createdByDisplayName,
'createdAt' => $this->createdAt,
Expand Down
17 changes: 17 additions & 0 deletions lib/Db/Row2.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class Row2 implements JsonSerializable {
private ?string $lastEditBy = null;
private ?string $lastEditAt = null;
private ?array $data = [];
/** @var array<string, array{columnId: int, value: mixed}> */
private array $dataByAlias = [];
private array $changedColumnIds = []; // collect column ids that have changed after $loaded = true

private bool $loaded = false; // set to true if model is loaded, after that changed column ids will be collected
Expand Down Expand Up @@ -73,6 +75,20 @@ public function getData(): ?array {
return $this->data;
}

/**
* @return array<string, array{columnId: int, value: mixed}>
*/
public function getDataByAlias(): array {
return $this->dataByAlias;
}

/**
* @param array<string, array{columnId: int, value: mixed}> $dataByAlias
*/
public function setDataByAlias(array $dataByAlias): void {
$this->dataByAlias = $dataByAlias;
}

/**
* @param RowDataInput|list<array{columnId: int, value: mixed}> $data
* @return void
Expand Down Expand Up @@ -145,6 +161,7 @@ public function jsonSerialize(): array {
'lastEditBy' => $this->lastEditBy,
'lastEditAt' => $this->lastEditAt,
'data' => $this->data,
'dataByAlias' => $this->dataByAlias,
];
}

Expand Down
6 changes: 6 additions & 0 deletions lib/Dto/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class Column {
public function __construct(
private ?string $title = null,
private ?string $technicalName = null,
private ?string $type = null,
private ?string $subtype = null,
private ?bool $mandatory = null,
Expand Down Expand Up @@ -45,6 +46,7 @@ public static function createFromArray(array $data): self {

return new self(
title: $data['title'] ?? null,
technicalName: $data['technicalName'] ?? null,
type: $data['type'] ?? null,
subtype: $data['subtype'] ?? null,
mandatory: $data['mandatory'] ?? null,
Expand Down Expand Up @@ -88,6 +90,10 @@ public function getTitle(): ?string {
return $this->title;
}

public function getTechnicalName(): ?string {
return $this->technicalName;
}

public function getDescription(): ?string {
return $this->description;
}
Expand Down
84 changes: 84 additions & 0 deletions lib/Migration/Version1000Date20260327000000.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

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

namespace OCA\Tables\Migration;

use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use Override;

class Version1000Date20260327000000 extends SimpleMigrationStep {
private IDBConnection $connection;

public function __construct(IDBConnection $connection) {
$this->connection = $connection;
}

#[Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();

if (!$schema->hasTable('tables_columns')) {
return null;
}

$table = $schema->getTable('tables_columns');
if (!$table->hasColumn('technical_name')) {
$table->addColumn('technical_name', Types::STRING, [
'notnull' => false,
'length' => 200,
]);
}

if (!$table->hasIndex('tables_columns_table_tech_name_uq')) {
$table->addUniqueIndex(['table_id', 'technical_name'], 'tables_columns_table_tech_name_uq');
}

return $schema;
}

#[Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$selectQb = $this->connection->getQueryBuilder();
$selectQb->select('id')
->from('tables_columns')
->where(
$selectQb->expr()->orX(
$selectQb->expr()->isNull('technical_name'),
$selectQb->expr()->eq('technical_name', $selectQb->createNamedParameter('')),
)
);

$result = $selectQb->executeQuery();
$updatedCount = 0;

try {
while ($row = $result->fetchAssociative()) {
$columnId = (int)$row['id'];

$updateQb = $this->connection->getQueryBuilder();
$updateQb->update('tables_columns')
->set('technical_name', $updateQb->createNamedParameter('column_' . $columnId, IQueryBuilder::PARAM_STR))
->where($updateQb->expr()->eq('id', $updateQb->createNamedParameter($columnId, IQueryBuilder::PARAM_INT)));

$updatedCount += $updateQb->executeStatement();
}
} finally {
$result->closeCursor();
}

$output->info('Version1000Date20260327000000: backfilled technical_name for ' . $updatedCount . ' columns.');
}
}
Loading
Loading