UPSTREAM BASELINE: nextcloud/spreed v22.0.12 (без изменений)
Type checking / changes (push) Has been cancelled
Type checking / test (push) Has been cancelled
Type checking / typescript-summary (push) Has been cancelled
Node tests / changes (push) Has been cancelled
Node tests / test (push) Has been cancelled
Node tests / test-summary (push) Has been cancelled

Источник: https://github.com/nextcloud/spreed/archive/refs/tags/v22.0.12.tar.gz
С этого коммита ветка официального Nextcloud Talk отрезана (решение владельца 2026-07-06).
Все дальнейшие изменения — только наши; версии релизов: 22.0.12-f7.N.
This commit is contained in:
2026-07-06 14:07:50 +00:00
commit 01acfa3b40
1716 changed files with 613013 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCA\Talk\Model\Attendee;
use OCP\IDBConnection;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
class CacheUserDisplayNames implements IRepairStep {
public function __construct(
protected IDBConnection $connection,
protected IUserManager $userManager,
) {
}
#[\Override]
public function getName(): string {
return 'Cache the user display names';
}
#[\Override]
public function run(IOutput $output): void {
$update = $this->connection->getQueryBuilder();
$update->update('talk_attendees')
->set('display_name', $update->createParameter('displayName'))
->where($update->expr()->eq('actor_type', $update->createParameter('actorType')))
->andWhere($update->expr()->eq('actor_id', $update->createParameter('actorId')));
$query = $this->connection->getQueryBuilder();
$query->select('actor_id')
->from('talk_attendees')
->where($query->expr()->eq('actor_type', $query->createNamedParameter(Attendee::ACTOR_USERS)))
->andWhere($query->expr()->eq('display_name', $query->createNamedParameter('')))
->groupBy('actor_id');
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$user = $this->userManager->get($row['actor_id']);
if (!$user instanceof IUser) {
continue;
}
$update->setParameter('displayName', $user->getDisplayName())
->setParameter('actorType', Attendee::ACTOR_USERS)
->setParameter('actorId', $row['actor_id']);
$update->executeStatement();
}
$result->closeCursor();
}
}
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCA\Talk\Collaboration\Resources\ConversationProvider;
use OCP\Collaboration\Resources\IManager;
use OCP\IConfig;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
class ClearResourceAccessCache implements IRepairStep {
protected const INVALIDATIONS = 1;
public function __construct(
protected IConfig $config,
protected IManager $manager,
protected ConversationProvider $provider,
) {
}
#[\Override]
public function getName(): string {
return 'Invalidate access cache for projects conversation provider';
}
#[\Override]
public function run(IOutput $output): void {
$invalidatedCache = (int)$this->config->getAppValue('spreed', 'project_access_invalidated', '0');
if ($invalidatedCache === self::INVALIDATIONS) {
$output->info('Invalidation not required');
return;
}
$this->manager->invalidateAccessCacheForProvider($this->provider);
$this->config->setAppValue('spreed', 'project_access_invalidated', (string)self::INVALIDATIONS);
}
}
+53
View File
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCA\Talk\Chat\ChatManager;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
/**
* In previous versions of Talk, the value 0 was used to mark a chat as
* completely unread. This meant that the next time a client/browser loaded the
* chat it would start all from the beginning. However, there were various
* issues over the time that made the frontend getting `null` or `undefined`
* into the wrong place and then accidentally loading 8 years of chat from the
* beginning. So it was agreed that the frontend manually blocks loading with
* last-read-message=0 and the special cases use -2 for this situation.
*/
class FixLastReadMessageZero implements IRepairStep {
public function __construct(
protected IDBConnection $connection,
) {
}
#[\Override]
public function getName(): string {
return 'Fix the namespace in database tables';
}
#[\Override]
public function run(IOutput $output): void {
$update = $this->connection->getQueryBuilder();
$update->update('talk_attendees')
/**
* -2 is {@see ChatManager::UNREAD_FIRST_MESSAGE}, but we can't use
* it in update code, because ChatManager is already loaded with the
* previous implementation.
*/
->set('last_read_message', $update->createNamedParameter(-2, IQueryBuilder::PARAM_INT))
->where($update->expr()->eq('last_read_message', $update->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
$updatedEntries = $update->executeStatement();
if ($updatedEntries) {
$output->info($updatedEntries . ' attendees have been updated.');
}
}
}
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
class FixNamespaceInDatabaseTables implements IRepairStep {
public function __construct(
protected IDBConnection $connection,
) {
}
#[\Override]
public function getName(): string {
return 'Fix the namespace in database tables';
}
#[\Override]
public function run(IOutput $output): void {
$update = $this->connection->getQueryBuilder();
$update->update('jobs')
->set('class', $update->createParameter('newClass'))
->where($update->expr()->eq('id', $update->createParameter('id')));
$query = $this->connection->getQueryBuilder();
$query->select('id', 'class')
->from('jobs')
->where($query->expr()->like('class', $query->createNamedParameter(
'%' . $this->connection->escapeLikeParameter('Spreed') . '%'
)));
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$oldClass = $row['class'];
if (!str_starts_with($oldClass, 'OCA\\Spreed\\')) {
continue;
}
$newClass = 'OCA\\Talk\\' . substr($oldClass, strlen('OCA\\Spreed\\'));
$update->setParameter('newClass', $newClass)
->setParameter('id', $row['id']);
$update->executeStatement();
}
$result->closeCursor();
}
}
+48
View File
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCA\Talk\Config;
use OCP\AppFramework\Services\IAppConfig;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
/**
* In JWT 7.0.2 validation for the key length was added, and it revealed that
* Talk used a too short private key. So when generating a signaling ticket fails,
* we generate a new private and public key with more complex curve which fixes it.
*/
class RegenerateSignalingKeys implements IRepairStep {
public function __construct(
protected IAppConfig $appConfig,
protected Config $talkConfig,
) {
}
#[\Override]
public function getName(): string {
return 'Regenerate signaling keys';
}
#[\Override]
public function run(IOutput $output): void {
$alg = $this->talkConfig->getSignalingTokenAlgorithm();
if ($alg === 'ES384') {
try {
$this->talkConfig->getSignalingTicket(2, null);
} catch (\Exception $e) {
$this->appConfig->setAppValue('signaling_token_privkey_' . strtolower($alg), '');
$this->appConfig->setAppValue('signaling_token_pubkey_' . strtolower($alg), '');
$this->talkConfig->getSignalingTokenPrivateKey($alg);
}
}
}
}
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version10000Date20200819121721 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_bridges')) {
$table = $schema->createTable('talk_bridges');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('room_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->addColumn('json_values', Types::TEXT, [
'notnull' => true,
]);
$table->addUniqueIndex(['room_id'], 'tbr_room_id');
$table->setPrimaryKey(['id']);
}
return $schema;
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version10000Date20201012144235 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @return ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('sip_enabled')) {
$table->addColumn('sip_enabled', Types::SMALLINT, [
'notnull' => true,
'default' => 0,
'unsigned' => true,
]);
}
return $schema;
}
}
@@ -0,0 +1,228 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Participant;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\DB\Exception;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* In order to be able to keep "attendees" which are not users, but groups,
* email addresses, etc the sessions had to be decoupled from the participants
*/
class Version10000Date20201015134000 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
protected ITimeFactory $timeFactory,
) {
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_attendees')) {
$table = $schema->createTable('talk_attendees');
// Auto increment id
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
// Unique key
$table->addColumn('room_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->addColumn('actor_type', Types::STRING, [
'notnull' => true,
'length' => 32,
]);
$table->addColumn('actor_id', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('display_name', Types::STRING, [
'notnull' => false,
'default' => '',
'length' => 64,
]);
$table->addColumn('pin', Types::STRING, [
'notnull' => false,
'length' => 32,
]);
$table->addColumn('participant_type', Types::SMALLINT, [
'notnull' => true,
'length' => 6,
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('favorite', Types::BOOLEAN, [
'default' => 0,
'notnull' => false,
]);
$table->addColumn('notification_level', Types::INTEGER, [
'default' => Participant::NOTIFY_DEFAULT,
'notnull' => false,
]);
$table->addColumn('last_joined_call', Types::INTEGER, [
'notnull' => true,
'length' => 11,
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('last_read_message', Types::BIGINT, [
'default' => 0,
'notnull' => false,
]);
$table->addColumn('last_mention_message', Types::BIGINT, [
'default' => 0,
'notnull' => false,
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['room_id', 'actor_type', 'actor_id'], 'ta_ident');
$table->addIndex(['room_id', 'pin'], 'ta_roompin');
//$table->addIndex(['room_id'], 'ta_room'); Removed in Version20000Date20240717180417
$table->addIndex(['actor_type', 'actor_id'], 'ta_actor');
}
if (!$schema->hasTable('talk_sessions')) {
$table = $schema->createTable('talk_sessions');
// Auto increment id
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
// Unique key (for now, might remove this in the future,
// so a user can join multiple times.
$table->addColumn('attendee_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
// Unique key to avoid duplication issues
$table->addColumn('session_id', Types::STRING, [
'notnull' => true,
'length' => 512,
]);
$table->addColumn('in_call', Types::INTEGER, [
'default' => 0,
]);
$table->addColumn('last_ping', Types::INTEGER, [
'notnull' => true,
'length' => 11,
'default' => 0,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['attendee_id'], 'ts_attendee');
$table->addUniqueIndex(['session_id'], 'ts_session');
$table->addIndex(['in_call'], 'ts_in_call');
$table->addIndex(['last_ping'], 'ts_last_ping');
}
return $schema;
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
#[\Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$insert = $this->connection->getQueryBuilder();
$insert->insert('talk_attendees')
->values([
'room_id' => $insert->createParameter('room_id'),
'actor_type' => $insert->createParameter('actor_type'),
'actor_id' => $insert->createParameter('actor_id'),
'participant_type' => $insert->createParameter('participant_type'),
'favorite' => $insert->createParameter('favorite'),
'notification_level' => $insert->createParameter('notification_level'),
'last_joined_call' => $insert->createParameter('last_joined_call'),
'last_read_message' => $insert->createParameter('last_read_message'),
'last_mention_message' => $insert->createParameter('last_mention_message'),
]);
$query = $this->connection->getQueryBuilder();
$query->select('*')
->from('talk_participants')
->where($query->expr()->neq('user_id', $query->createNamedParameter('')))
->andWhere($query->expr()->isNotNull('user_id'));
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$lastJoinedCall = 0;
if (!empty($row['last_joined_call'])) {
$lastJoinedCall = $this->timeFactory->getDateTime($row['last_joined_call'])->getTimestamp();
}
$insert
->setParameter('room_id', (int)$row['room_id'], IQueryBuilder::PARAM_INT)
->setParameter('actor_type', Attendee::ACTOR_USERS)
->setParameter('actor_id', $row['user_id'])
->setParameter('participant_type', (int)$row['participant_type'], IQueryBuilder::PARAM_INT)
->setParameter('favorite', (bool)$row['favorite'], IQueryBuilder::PARAM_BOOL)
->setParameter('notification_level', (int)$row['notification_level'], IQueryBuilder::PARAM_INT)
->setParameter('last_joined_call', $lastJoinedCall, IQueryBuilder::PARAM_INT)
->setParameter('last_read_message', (int)$row['last_read_message'], IQueryBuilder::PARAM_INT)
->setParameter('last_mention_message', (int)$row['last_mention_message'], IQueryBuilder::PARAM_INT)
;
try {
$insert->executeStatement();
} catch (\Exception $e) {
if (class_exists(UniqueConstraintViolationException::class)
&& $e instanceof UniqueConstraintViolationException) {
// UniqueConstraintViolationException before 21
continue;
}
if (class_exists(Exception::class)
&& $e instanceof Exception
// Exception with 21 and later
&& $e->getReason() === Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
continue;
}
throw $e;
}
}
$result->closeCursor();
}
}
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version10000Date20201015143852 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_participants')) {
$schema->dropTable('talk_participants');
return $schema;
}
return null;
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* The HPB is generating sessions longer than 255 chars. So we update the length
* But the install migration was fixed, so this only does something on update.
*/
class Version10000Date20201015150000 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_sessions')) {
$table = $schema->getTable('talk_sessions');
$column = $table->getColumn('session_id');
if ($column->getLength() !== 512) {
$column->setLength(512);
return $schema;
}
}
return null;
}
}
@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\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;
class Version11000Date20200922161218 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_bridges')) {
$table = $schema->getTable('talk_bridges');
if (!$table->hasColumn('enabled')) {
$table->addColumn('enabled', Types::SMALLINT, [
'notnull' => true,
'default' => 0,
'unsigned' => true,
]);
}
if (!$table->hasColumn('pid')) {
$table->addColumn('pid', Types::INTEGER, [
'notnull' => true,
'default' => 0,
'unsigned' => true,
]);
}
}
return $schema;
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
#[\Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$query = $this->connection->getQueryBuilder();
$bridges = [];
$query->select('id', 'json_values')
->from('talk_bridges');
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$bridges[] = [
'id' => $row['id'],
'json_values' => $row['json_values'],
];
}
$result->closeCursor();
if (empty($bridges)) {
return;
}
$update = $this->connection->getQueryBuilder();
$update->update('talk_bridges')
->set('enabled', $update->createParameter('enabled'))
->set('pid', $update->createParameter('pid'))
->set('json_values', $update->createParameter('json_values'))
->where($update->expr()->eq('id', $update->createParameter('id')));
foreach ($bridges as $bridge) {
$values = json_decode($bridge['json_values'], true);
if (isset($values['pid'], $values['enabled'])) {
$intEnabled = $values['enabled'] ? 1 : 0;
$newValues = $values['parts'] ?: [];
$encodedNewValues = json_encode($newValues);
$update->setParameter('enabled', $intEnabled, IQueryBuilder::PARAM_INT)
->setParameter('pid', $values['pid'], IQueryBuilder::PARAM_INT)
->setParameter('json_values', $encodedNewValues, IQueryBuilder::PARAM_STR)
->setParameter('id', $bridge['id'], IQueryBuilder::PARAM_INT);
$update->executeStatement();
}
}
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version11000Date20201011082810 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('description')) {
$table->addColumn('description', Types::TEXT, [
'notnull' => false,
'default' => '',
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Add listable column to the rooms table.
*/
class Version11000Date20201201102528 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_rooms')) {
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('listable')) {
$table->addColumn('listable', Types::SMALLINT, [
'notnull' => false,
'default' => 0,
'unsigned' => true,
]);
}
if (!$table->hasIndex('tr_listable')) {
$table->addIndex(['listable'], 'tr_listable');
}
return $schema;
}
return null;
}
}
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version11000Date20201204110210 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_attendees')) {
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('read_privacy')) {
$table->addColumn('read_privacy', Types::SMALLINT, [
'notnull' => false,
'default' => 0,
'unsigned' => true,
]);
return $schema;
}
}
return null;
}
}
@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version11000Date20201209142525 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$changedSchema = false;
if (!$schema->hasTable('talk_internalsignaling')) {
$table = $schema->createTable('talk_internalsignaling');
// Auto increment id
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('sender', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('recipient', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('message', Types::TEXT, [
'notnull' => true,
]);
$table->addColumn('timestamp', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['recipient', 'timestamp'], 'tis_recipient_time');
$changedSchema = true;
}
if (!$schema->hasTable('talk_guestnames')) {
$table = $schema->createTable('talk_guestnames');
// Auto increment id
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('session_hash', Types::STRING, [
'notnull' => false,
'length' => 64,
]);
$table->addColumn('display_name', Types::STRING, [
'notnull' => false,
'length' => 64,
'default' => '',
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['session_hash'], 'tgn_session_hash');
$changedSchema = true;
}
return $changedSchema ? $schema : null;
}
}
@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version11000Date20201209142526 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$changedSchema = false;
if ($schema->hasTable('talk_signaling')) {
$schema->dropTable('talk_signaling');
$changedSchema = true;
}
if ($schema->hasTable('talk_guests')) {
$schema->dropTable('talk_guests');
$changedSchema = true;
}
return $changedSchema ? $schema : null;
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version11001Date20210211111527 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('call_flag')) {
$table->addColumn('call_flag', Types::INTEGER, [
'default' => 0,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version11001Date20210212105406 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
/**
* Table is dropped in favor of talk_attendees::display_name
* We can't link the data to a room and therefor create a related
* attendee, so unluckily it makes no sense to take over the data
*/
if ($schema->hasTable('talk_guestnames')) {
$schema->dropTable('talk_guestnames');
return $schema;
}
return null;
}
}
@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Replace the former unique attendee key with a normal index
* allowing an attendee to have multiple sessions in the same conversation.
*/
class Version12000Date20210217134030 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_sessions');
if ($table->hasIndex('ts_attendee')) {
$table->dropIndex('ts_attendee');
}
if (!$table->hasIndex('ts_attendee_id')) {
$table->addIndex(['attendee_id'], 'ts_attendee_id');
}
return $schema;
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version12000Date20210401124139 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$result = $this->ensureColumnIsNullable($schema, 'talk_attendees', 'favorite');
return $result ? $schema : null;
}
protected function ensureColumnIsNullable(ISchemaWrapper $schema, string $tableName, string $columnName): bool {
$table = $schema->getTable($tableName);
$column = $table->getColumn($columnName);
if ($column->getNotnull()) {
$column->setNotnull(false);
return true;
}
return false;
}
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version12000Date20210528100404 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
// Obsoleted by Version13000Date20210921142733
// /** @var ISchemaWrapper $schema */
// $schema = $schemaClosure();
//
// $table = $schema->getTable('talk_attendees');
// if (!$table->hasColumn('publishing_permissions')) {
// $table->addColumn('publishing_permissions', Types::INTEGER, [
// 'default' => 7,
// ]);
//
// return $schema;
// }
return null;
}
}
@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use Doctrine\DBAL\Schema\SchemaException;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version13000Date20210625232111 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @throws SchemaException
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('access_token')) {
$table->addColumn('access_token', Types::STRING, [
'notnull' => false,
'default' => null,
'length' => 64
]);
}
if (!$table->hasColumn('remote_id')) {
$table->addColumn('remote_id', Types::STRING, [
'notnull' => false,
'default' => null,
'length' => 255,
]);
}
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('server_url')) {
$table->addColumn('server_url', Types::STRING, [
'notnull' => false,
'default' => null,
]);
}
/** Removed in {@see Version18000Date20231024141626} */
/** Recreated in {@see Version18000Date20231024141627} */
// if (!$schema->hasTable('talk_invitations')) {
// $table = $schema->createTable('talk_invitations');
// $table->addColumn('id', Types::BIGINT, [
// 'autoincrement' => true,
// 'notnull' => true,
// ]);
// $table->addColumn('room_id', Types::BIGINT, [
// 'notnull' => true,
// 'unsigned' => true,
// ]);
// $table->addColumn('user_id', Types::STRING, [
// 'notnull' => true,
// 'length' => 255,
// ]);
// $table->addColumn('access_token', Types::STRING, [
// 'notnull' => true,
// 'length' => 64,
// ]);
// $table->addColumn('remote_id', Types::STRING, [
// 'notnull' => true,
// 'length' => 255,
// ]);
//
// $table->setPrimaryKey(['id']);
//
// $table->addIndex(['room_id']);
// }
return $schema;
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version13000Date20210901164235 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('last_mention_direct')) {
$table->addColumn('last_mention_direct', Types::BIGINT, [
'default' => 0,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version13000Date20210921142733 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if ($table->hasColumn('publishing_permissions')) {
$table->dropColumn('publishing_permissions');
}
if (!$table->hasColumn('permissions')) {
$table->addColumn('permissions', Types::INTEGER, [
'default' => 0,
]);
}
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('default_permissions')) {
$table->addColumn('default_permissions', Types::INTEGER, [
'default' => 0,
]);
}
if (!$table->hasColumn('call_permissions')) {
$table->addColumn('call_permissions', Types::INTEGER, [
'default' => 0,
]);
}
return $schema;
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
#[\Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
// FIXME set default_permissions based on appconfig "start_calls"
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCA\Talk\Participant;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version13000Date20211007192733 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('notification_calls')) {
$table->addColumn('notification_calls', Types::INTEGER, [
'default' => Participant::NOTIFY_CALLS_ON,
]);
}
return $schema;
}
}
@@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version14000Date20211203132513 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('remote_server')) {
$table->addColumn('remote_server', Types::STRING, [
'notnull' => false,
'length' => 512,
'default' => null,
]);
$table->addColumn('remote_token', Types::STRING, [
'notnull' => false,
'length' => 32,
'default' => null,
]);
// Can not be unique as we have null, null for all local rooms.
$table->addIndex(['remote_server', 'remote_token'], 'remote_id');
}
if ($table->hasColumn('server_url')) {
$table->dropColumn('server_url');
}
return $schema;
}
}
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\IConfig;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version14000Date20220217115327 extends SimpleMigrationStep {
public function __construct(
protected IConfig $config,
) {
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
#[\Override]
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$this->config->deleteAppValue('spreed', 'hosted-signaling-server-account-last-checked');
}
}
@@ -0,0 +1,37 @@
<?php
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
declare(strict_types=1);
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version14000Date20220328153054 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
$displayName = $table->getColumn('display_name');
if ($displayName->getLength() !== 255) {
$displayName->setLength(255);
return $schema;
}
return null;
}
}
@@ -0,0 +1,219 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCA\Talk\Model\Attachment;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version14000Date20220330141647 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_attachments')) {
$table = $schema->createTable('talk_attachments');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('room_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->addColumn('message_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->addColumn('message_time', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->addColumn('object_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('actor_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('actor_id', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['room_id', 'object_type'], 'objects_in_room');
return $schema;
}
return null;
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
#[\Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$sql = $this->connection->getDatabasePlatform()
->getTruncateTableSQL('`*PREFIX*talk_attachments`');
$this->connection->executeQuery($sql);
$insert = $this->connection->getQueryBuilder();
$insert->insert('talk_attachments')
->setValue('room_id', $insert->createParameter('room_id'))
->setValue('message_id', $insert->createParameter('message_id'))
->setValue('message_time', $insert->createParameter('message_time'))
->setValue('object_type', $insert->createParameter('object_type'))
->setValue('actor_type', $insert->createParameter('actor_type'))
->setValue('actor_id', $insert->createParameter('actor_id'));
$offset = -1;
$select = $this->connection->getQueryBuilder();
$select->select('id', 'creation_timestamp', 'object_id', 'actor_type', 'actor_id', 'message')
->from('comments')
->where($select->expr()->eq('object_type', $select->createParameter('object_type')))
->andWhere($select->expr()->eq('verb', $select->createParameter('verb')))
->andWhere($select->expr()->gt('id', $select->createParameter('offset')))
->orderBy('id', 'ASC')
->setMaxResults(1000);
$select->setParameter('object_type', 'chat')
->setParameter('verb', 'object_shared');
while ($offset !== 0) {
$offset = $this->chunkedWriting($insert, $select, max($offset, 0));
}
}
protected function chunkedWriting(IQueryBuilder $insert, IQueryBuilder $select, int $offset): int {
$select->setParameter('offset', $offset);
$attachments = $sharesWithoutMimetype = [];
$result = $select->executeQuery();
while ($row = $result->fetch()) {
$attachment = [
'room_id' => (int)$row['object_id'],
'message_id' => (int)$row['id'],
'actor_type' => $row['actor_type'],
'actor_id' => $row['actor_id'],
];
$datetime = new \DateTime($row['creation_timestamp']);
$attachment['message_time'] = $datetime->getTimestamp();
$message = json_decode($row['message'], true);
$messageType = $message['message'] ?? '';
$parameters = $message['parameters'] ?? [];
if ($messageType === 'object_shared') {
$objectType = $parameters['objectType'] ?? '';
if ($objectType === 'geo-location') {
$attachment['object_type'] = Attachment::TYPE_LOCATION;
} elseif ($objectType === 'deck-card') {
$attachment['object_type'] = Attachment::TYPE_DECK_CARD;
} else {
$attachment['object_type'] = Attachment::TYPE_OTHER;
}
} else {
$messageType = $parameters['metaData']['messageType'] ?? '';
$mimetype = $parameters['metaData']['mimeType'] ?? '';
if ($messageType === 'voice-message') {
$attachment['object_type'] = Attachment::TYPE_VOICE;
} elseif (str_starts_with($mimetype, 'audio/')) {
$attachment['object_type'] = Attachment::TYPE_AUDIO;
} elseif (str_starts_with($mimetype, 'image/') || str_starts_with($mimetype, 'video/')) {
$attachment['object_type'] = Attachment::TYPE_MEDIA;
} else {
if ($mimetype === '' && isset($parameters['share'])) {
$sharesWithoutMimetype[(int)$parameters['share']] = (int)$row['id'];
}
$attachment['object_type'] = Attachment::TYPE_FILE;
}
}
$attachments[(int)$row['id']] = $attachment;
}
$result->closeCursor();
if (empty($attachments)) {
return 0;
}
$mimetypes = $this->getMimetypeFromFileCache(array_keys($sharesWithoutMimetype));
foreach ($mimetypes as $shareId => $mimetype) {
if (!isset($attachments[$sharesWithoutMimetype[$shareId]])) {
continue;
}
if (str_starts_with($mimetype, 'audio/')) {
$attachments[$sharesWithoutMimetype[$shareId]]['object_type'] = Attachment::TYPE_AUDIO;
} elseif (str_starts_with($mimetype, 'image/') || str_starts_with($mimetype, 'video/')) {
$attachments[$sharesWithoutMimetype[$shareId]]['object_type'] = Attachment::TYPE_MEDIA;
}
}
$this->connection->beginTransaction();
foreach ($attachments as $attachment) {
$insert
->setParameter('room_id', $attachment['room_id'], IQueryBuilder::PARAM_INT)
->setParameter('message_id', $attachment['message_id'], IQueryBuilder::PARAM_INT)
->setParameter('message_time', $attachment['message_time'], IQueryBuilder::PARAM_INT)
->setParameter('actor_type', $attachment['actor_type'])
->setParameter('actor_id', $attachment['actor_id'])
->setParameter('object_type', $attachment['object_type'])
;
$insert->executeStatement();
}
$this->connection->commit();
return end($attachments)['message_id'];
}
protected function getMimetypeFromFileCache(array $shareIds): array {
$mimetype = [];
$query = $this->connection->getQueryBuilder();
$query->select('s.id', 'm.mimetype')
->from('share', 's')
->leftJoin('s', 'filecache', 'f', $query->expr()->eq('s.file_source', 'f.fileid'))
->leftJoin('f', 'mimetypes', 'm', $query->expr()->eq('f.mimetype', 'm.id'))
->where($query->expr()->in('s.id', $query->createNamedParameter($shareIds, IQueryBuilder::PARAM_INT_ARRAY)));
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$mimetype[$row['id']] = $row['mimetype'];
}
$result->closeCursor();
return $mimetype;
}
}
@@ -0,0 +1,97 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version15000Date20220427183026 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* Update existing permissions by adding the chat permissions when set to none default
*
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `\OCP\DB\ISchemaWrapper`
* @param array $options
*/
#[\Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$update = $this->connection->getQueryBuilder();
$update->update('talk_rooms')
->set('default_permissions', $update->func()->add(
'default_permissions',
$update->createNamedParameter(128, IQueryBuilder::PARAM_INT) // Attendee::PERMISSION_CHAT
))
->where($update->expr()->neq('default_permissions', $update->createNamedParameter(0, IQueryBuilder::PARAM_INT))) // Attendee::PERMISSIONS_DEFAULT
->andWhere(
$update->expr()->neq(
$update->expr()->castColumn(
$update->expr()->bitwiseAnd(
'default_permissions',
128 // Attendee::PERMISSION_CHAT
),
IQueryBuilder::PARAM_INT
),
$update->createNamedParameter(128, IQueryBuilder::PARAM_INT) // Attendee::PERMISSION_CHAT
)
);
$update->executeStatement();
$update = $this->connection->getQueryBuilder();
$update->update('talk_rooms')
->set('call_permissions', $update->func()->add(
'call_permissions',
$update->createNamedParameter(128, IQueryBuilder::PARAM_INT) // Attendee::PERMISSION_CHAT
))
->where($update->expr()->neq('call_permissions', $update->createNamedParameter(0, IQueryBuilder::PARAM_INT))) // Attendee::PERMISSIONS_DEFAULT
->andWhere(
$update->expr()->neq(
$update->expr()->castColumn(
$update->expr()->bitwiseAnd(
'call_permissions',
128 // Attendee::PERMISSION_CHAT
),
IQueryBuilder::PARAM_INT
),
$update->createNamedParameter(128, IQueryBuilder::PARAM_INT) // Attendee::PERMISSION_CHAT
)
);
$update->executeStatement();
$update = $this->connection->getQueryBuilder();
$update->update('talk_attendees')
->set('permissions', $update->func()->add(
'permissions',
$update->createNamedParameter(128, IQueryBuilder::PARAM_INT) // Attendee::PERMISSION_CHAT
))
->where($update->expr()->neq('permissions', $update->createNamedParameter(0, IQueryBuilder::PARAM_INT))) // Attendee::PERMISSIONS_DEFAULT
->andWhere(
$update->expr()->neq(
$update->expr()->castColumn(
$update->expr()->bitwiseAnd(
'permissions',
128 // Attendee::PERMISSION_CHAT
),
IQueryBuilder::PARAM_INT
),
$update->createNamedParameter(128, IQueryBuilder::PARAM_INT) // Attendee::PERMISSION_CHAT
)
);
$update->executeStatement();
}
}
@@ -0,0 +1,128 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version15000Date20220503121308 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_polls')) {
$table = $schema->createTable('talk_polls');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('room_id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
]);
$table->addColumn('question', Types::TEXT, [
'notnull' => false,
'length' => null,
]);
$table->addColumn('options', Types::TEXT, [
'notnull' => false,
'length' => null,
]);
$table->addColumn('votes', Types::TEXT, [
'notnull' => false,
'length' => null,
]);
$table->addColumn('num_voters', Types::BIGINT, [
'notnull' => false,
'length' => 20,
'default' => 0,
]);
$table->addColumn('actor_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('actor_id', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('display_name', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('status', Types::SMALLINT, [
'notnull' => false,
'default' => 0,
]);
$table->addColumn('result_mode', Types::SMALLINT, [
'notnull' => false,
'default' => 0,
]);
$table->addColumn('max_votes', Types::INTEGER, [
'notnull' => true,
'default' => 0,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['room_id'], 'talk_poll_room');
}
if (!$schema->hasTable('talk_poll_votes')) {
$table = $schema->createTable('talk_poll_votes');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('poll_id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
]);
$table->addColumn('room_id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
]);
$table->addColumn('actor_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('actor_id', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('display_name', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('option_id', Types::INTEGER, [
'notnull' => true,
'length' => 6,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['poll_id', 'actor_type', 'actor_id'], 'talk_poll_vote');
$table->addIndex(['room_id'], 'talk_vote_room');
}
return $schema;
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version15000Date20220506005058 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('message_expiration')) {
$table->addColumn('message_expiration', Types::INTEGER, [
'default' => 0,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Breakout rooms configuration
*/
class Version16000Date20221110151714 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('breakout_room_mode')) {
$table->addColumn('breakout_room_mode', Types::INTEGER, [
'default' => 0,
]);
$table->addColumn('breakout_room_status', Types::INTEGER, [
'default' => 0,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version16000Date20221116163301 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('avatar')) {
$table->addColumn('avatar', Types::STRING, [
'notnull' => false,
'length' => 24,
'default' => '',
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version16000Date20221208013745 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('call_recording')) {
$table->addColumn('call_recording', Types::INTEGER, [
'default' => 0,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Participant;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version16000Date20230502145340 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
#[\Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$query = $this->connection->getQueryBuilder();
$query->update('talk_attendees')
->set('permissions', $query->createNamedParameter(Attendee::PERMISSIONS_DEFAULT, IQueryBuilder::PARAM_INT))
->where($query->expr()->eq('participant_type', $query->createNamedParameter(Participant::MODERATOR)))
->orWhere($query->expr()->eq('participant_type', $query->createNamedParameter(Participant::GUEST_MODERATOR)));
$fixed = $query->executeStatement();
$output->info('Fixed permissions of ' . $fixed . ' moderators');
}
}
@@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20230504205823 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return ?ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_bots_server')) {
$table = $schema->createTable('talk_bots_server');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('name', Types::STRING, [
'length' => 64,
]);
$table->addColumn('url', Types::STRING, [
'length' => 4000,
]);
$table->addColumn('url_hash', Types::STRING, [
'length' => 64,
]);
$table->addColumn('description', Types::STRING, [
'length' => 4000,
'notnull' => false,
]);
$table->addColumn('secret', Types::STRING, [
'length' => 128,
]);
$table->addColumn('error_count', Types::BIGINT, [
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('last_error_date', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('last_error_message', Types::STRING, [
'length' => 4000,
'notnull' => false,
]);
$table->addColumn('state', Types::SMALLINT, [
'default' => 0,
'notnull' => false,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['state'], 'talk_bots_server_state');
$table->addUniqueIndex(['url_hash'], 'talk_bots_server_urlhash');
$table->addUniqueIndex(['secret'], 'talk_bots_server_secret');
$table = $schema->createTable('talk_bots_conversation');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('bot_id', Types::BIGINT, [
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('token', Types::STRING, [
'length' => 64,
'notnull' => false,
]);
$table->addColumn('state', Types::SMALLINT, [
'default' => 0,
'notnull' => false,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['token', 'state'], 'talk_bots_convo_token');
//$table->addIndex(['bot_id'], 'talk_bots_convo_id'); Removed in Version20000Date20240717180417
$table->addUniqueIndex(['bot_id', 'token'], 'talk_bots_convo_uniq');
return $schema;
}
return null;
}
}
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20230808120823 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_reminders')) {
$table = $schema->createTable('talk_reminders');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('user_id', Types::STRING, [
'length' => 64,
]);
$table->addColumn('token', Types::STRING, [
'length' => 64,
]);
$table->addColumn('message_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->addColumn('date_time', Types::DATETIME, [
'notnull' => false,
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['user_id', 'message_id'], 'talk_reminder_user_msg');
$table->addIndex(['date_time'], 'talk_reminder_exectime');
return $schema;
}
return null;
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20230821112014 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_bots_server');
if (!$table->hasColumn('features')) {
$table->addColumn('features', Types::INTEGER, [
'default' => 3, // webhook + response
'unsigned' => true,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20230824123939 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$modified = false;
$table = $schema->getTable('talk_bots_server');
if (!$table->hasIndex('talk_bots_server_urlhash')) {
$table->addUniqueIndex(['url_hash'], 'talk_bots_server_urlhash');
$modified = true;
}
if (!$table->hasIndex('talk_bots_server_secret')) {
$table->addUniqueIndex(['secret'], 'talk_bots_server_secret');
$modified = true;
}
$table = $schema->getTable('talk_bots_conversation');
if (!$table->hasIndex('talk_bots_convo_uniq')) {
$table->addUniqueIndex(['bot_id', 'token'], 'talk_bots_convo_uniq');
$modified = true;
}
return $modified ? $schema : null;
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20230920182747 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_sessions');
if (!$table->hasColumn('state')) {
$table->addColumn('state', Types::SMALLINT, [
'default' => 1, // active
'unsigned' => true,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20230928131717 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('phone_number')) {
$table->addColumn('phone_number', Types::STRING, [
'notnull' => false,
'default' => '',
'length' => 255,
]);
$table->addColumn('call_id', Types::STRING, [
'notnull' => false,
'default' => '',
'length' => 255,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20231005091416 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('recording_consent')) {
$table->addColumn('recording_consent', Types::SMALLINT, [
'default' => 0,
'unsigned' => true,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20231018065816 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_consent')) {
$table = $schema->createTable('talk_consent');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('token', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('actor_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('actor_id', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('date_time', Types::DATETIME, [
'notnull' => false,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['token'], 'talk_reccons_token');
$table->addIndex(['actor_id', 'actor_type'], 'talk_reccons_actor');
return $schema;
}
return null;
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version18000Date20231024141626 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_invitations')) {
/** Recreated in {@see Version18000Date20231024141627} */
$schema->dropTable('talk_invitations');
return $schema;
}
return null;
}
}
@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Auto-generated migration step: Please modify to your needs!
*/
class Version18000Date20231024141627 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_invitations')) {
$table = $schema->createTable('talk_invitations');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('user_id', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('state', Types::SMALLINT, [
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('local_room_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->addColumn('access_token', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('remote_server_url', Types::STRING, [
'notnull' => true,
'length' => 512,
]);
$table->addColumn('remote_token', Types::STRING, [
'notnull' => true,
'length' => 32,
]);
$table->addColumn('remote_attendee_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['local_room_id'], 'talk_fedinv_lri');
$table->addUniqueIndex(['remote_server_url', 'remote_attendee_id'], 'talk_fedinv_remote');
return $schema;
}
return null;
}
}
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Add inviter information to the invites for rendering them outside of notifications later
*/
class Version19000Date20240212155937 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_invitations');
if (!$table->hasColumn('inviter_cloud_id')) {
$table->addColumn('inviter_cloud_id', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('inviter_display_name', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Add inviter information to the invites for rendering them outside of notifications later
*/
class Version19000Date20240214095011 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$changed = false;
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('invited_cloud_id')) {
$table->addColumn('invited_cloud_id', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$changed = true;
}
$table = $schema->getTable('talk_invitations');
if (!$table->hasColumn('local_cloud_id')) {
$table->addColumn('local_cloud_id', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$changed = true;
}
return $changed ? $schema : null;
}
}
@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* A temporary message cache for TalkV1 proxying to serve "last message" and help with notifications
*/
class Version19000Date20240227084313 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->createTable('talk_proxy_messages');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('local_token', Types::STRING, [
'notnull' => true,
'length' => 32,
]);
$table->addColumn('remote_server_url', Types::STRING, [
'notnull' => true,
'length' => 512,
]);
$table->addColumn('remote_token', Types::STRING, [
'notnull' => true,
'length' => 32,
]);
$table->addColumn('remote_message_id', Types::BIGINT, [
'notnull' => true,
'unsigned' => true,
]);
$table->addColumn('actor_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('actor_id', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('actor_display_name', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('message_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('system_message', Types::STRING, [
'notnull' => false,
'length' => 64,
]);
$table->addColumn('expiration_datetime', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('message', Types::TEXT, [
'notnull' => false,
]);
$table->addColumn('message_parameters', Types::TEXT, [
'notnull' => false,
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['remote_server_url', 'remote_token', 'remote_message_id'], 'talk_pcm_remote');
$table->addIndex(['local_token'], 'talk_pmc_local');
return $schema;
}
}
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Add creation datetime and meta-data columns to the proxy cache
*/
class Version19000Date20240305115243 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_proxy_messages');
if (!$table->hasColumn('creation_datetime')) {
$table->addColumn('creation_datetime', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('meta_data', Types::TEXT, [
'notnull' => false,
]);
return $schema;
}
return null;
}
}
@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Add table to queue federation notifications to retry
*/
class Version19000Date20240312105627 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->createTable('talk_retry_ocm');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
]);
$table->addColumn('remote_server', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('num_attempts', Types::INTEGER, [
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('next_retry', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('notification_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('resource_type', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('provider_id', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('notification', Types::TEXT, [
'notnull' => true,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['next_retry'], 'talk_retry_ocm_next');
return $schema;
}
/**
* Remove legacy RetryJobs
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
/** @psalm-suppress UndefinedClass */
$formerClassName = \OCA\Talk\BackgroundJob\RetryJob::class;
$query = $this->connection->getQueryBuilder();
$query->delete('jobs')
->where($query->expr()->eq('class', $query->createNamedParameter($formerClassName)));
$query->executeStatement();
}
}
@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Model\Invitation;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Cache the invite state in the attendees and room table to allow reducing efforts
*/
class Version19000Date20240313134926 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
$table->addColumn('state', Types::SMALLINT, [
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('unread_messages', Types::BIGINT, [
'default' => 0,
'unsigned' => true,
]);
$table = $schema->getTable('talk_rooms');
$table->addColumn('has_federation', Types::SMALLINT, [
'default' => 0,
'unsigned' => true,
]);
return $schema;
}
/**
* Set the invitation state to accepted for existing federated users
* Set the "has federation" for rooms with TalkV1 users
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
$query = $this->connection->getQueryBuilder();
$query->update('talk_attendees')
->set('state', $query->createNamedParameter(Invitation::STATE_ACCEPTED))
->where($query->expr()->eq('actor_type', $query->createNamedParameter(Attendee::ACTOR_FEDERATED_USERS)));
$query->executeStatement();
$query = $this->connection->getQueryBuilder();
$subQuery = $this->connection->getQueryBuilder();
$subQuery->select('room_id')
->from('talk_attendees')
->where($subQuery->expr()->eq('actor_type', $query->createNamedParameter(Attendee::ACTOR_FEDERATED_USERS)))
->groupBy('room_id');
$query = $this->connection->getQueryBuilder();
$query->update('talk_rooms')
// Don't use const Room::HAS_FEDERATION_TALKv1 because the file might have been loaded with old content before the migration
// ->set('has_federation', $query->createNamedParameter(Room::HAS_FEDERATION_TALKv1))
->set('has_federation', $query->createNamedParameter(1))
->where($query->expr()->in('id', $query->createFunction($subQuery->getSQL())));
$query->executeStatement();
}
}
@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Add a column to track the last read marker update so conversations marked
* as (un)read on other devices are properly updated with the "lazy" update.
*/
class Version19000Date20240416104656 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
$table->addColumn('last_attendee_activity', Types::BIGINT, [
'default' => 0,
'unsigned' => true,
]);
return $schema;
}
}
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Heal federation from before Nextcloud 29.0.4 which sends requests
* without the protocol on the remote in case it is https://
*/
class Version19000Date20240709183938 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
#[\Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$this->addMissingProtocol('talk_invitations', 'remote_server_url');
$this->addMissingProtocol('talk_proxy_messages', 'remote_server_url');
$this->addMissingProtocol('talk_rooms', 'remote_server');
}
protected function addMissingProtocol(string $table, string $column): void {
$query = $this->connection->getQueryBuilder();
$query->update($table)
->set($column, $query->func()->concat($query->createNamedParameter('https://'), $column))
->where($query->expr()->notLike($column, $query->createNamedParameter(
$this->connection->escapeLikeParameter('http://') . '%'
)))
->andWhere($query->expr()->notLike($column, $query->createNamedParameter(
$this->connection->escapeLikeParameter('https://') . '%'
)))
->andWhere($query->expr()->nonEmptyString($column));
$query->executeStatement();
}
}
@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version20000Date20240621150333 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
// The table was dropped in Version20000Date20240621150334 and recreated in Version20000Date20240621150335
// To be less error prone by explicitly naming the columns banned_* and moderator_*
// /** @var ISchemaWrapper $schema */
// $schema = $schemaClosure();
//
// if (!$schema->hasTable('talk_bans')) {
// $table = $schema->createTable('talk_bans');
// $table->addColumn('id', Types::BIGINT, [
// 'autoincrement' => true,
// 'notnull' => true,
// 'length' => 20,
// ]);
// $table->addColumn('actor_type', Types::STRING, [
// 'notnull' => true,
// 'length' => 64,
// ]);
// $table->addColumn('actor_id', Types::STRING, [
// 'notnull' => true,
// 'length' => 64,
// ]);
// $table->addColumn('room_id', Types::BIGINT, [
// 'notnull' => true,
// 'unsigned' => true,
// ]);
// $table->addColumn('banned_type', Types::STRING, [
// 'length' => 64,
// 'notnull' => true,
// ]);
// $table->addColumn('banned_id', Types::STRING, [
// 'length' => 64,
// 'notnull' => true,
// ]);
// $table->addColumn('banned_time', Types::DATETIME, [
// 'notnull' => false,
// ]);
// $table->addColumn('internal_note', Types::TEXT, [
// 'notnull' => false,
// ]);
//
// $table->setPrimaryKey(['id']);
// //A user should not be banned from the same room more than once
// $table->addUniqueIndex(['banned_type', 'banned_id', 'room_id'], 'talk_bans_unique_actor_room');
// $table->addIndex(['room_id']);
// return $schema;
// }
return null;
}
}
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version20000Date20240621150334 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_bans')) {
$schema->dropTable('talk_bans');
return $schema;
}
return null;
}
}
@@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version20000Date20240621150335 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_bans')) {
$table = $schema->createTable('talk_bans');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('moderator_actor_type', Types::STRING, [
'notnull' => true,
'length' => 32,
]);
$table->addColumn('moderator_actor_id', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('moderator_displayname', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('banned_actor_type', Types::STRING, [
'notnull' => true,
'length' => 32,
]);
$table->addColumn('banned_actor_id', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('banned_displayname', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('room_id', Types::BIGINT, [
'unsigned' => true,
]);
$table->addColumn('banned_time', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('internal_note', Types::TEXT, [
'notnull' => false,
]);
$table->setPrimaryKey(['id']);
//A user should not be banned from the same room more than once
$table->addUniqueIndex(['banned_actor_type', 'banned_actor_id', 'room_id'], 'talk_room_bans');
$table->addIndex(['room_id']);
return $schema;
}
return null;
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version20000Date20240623123938 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('mention_permissions')) {
$table->addColumn('mention_permissions', Types::INTEGER, [
'default' => 0,
'notnull' => true,
]);
}
return $schema;
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version20000Date20240716190335 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_invitations');
if (!$table->hasIndex('talk_user_state')) {
$table->addIndex(['user_id', 'state'], 'talk_user_state');
return $schema;
}
return null;
}
}
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version20000Date20240717180417 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
// Remove redundant index ta_room from talk_attendees
$table = $schema->getTable('talk_attendees');
if ($table->hasIndex('ta_room')) {
$table->dropIndex('ta_room');
}
// Remove redundant index talk_bots_convo_id from talk_bots_conversation
$table = $schema->getTable('talk_bots_conversation');
if ($table->hasIndex('talk_bots_convo_id')) {
$table->dropIndex('talk_bots_convo_id');
}
return $schema;
}
}
@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Adjust session id length in internal signaling messages to maximum Nextcloud
* session id length.
*/
class Version20000Date20240718031959 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_internalsignaling')) {
$table = $schema->getTable('talk_internalsignaling');
$modified = false;
$sender = $table->getColumn('sender');
if ($sender->getLength() !== 512) {
$sender->setLength(512);
$modified = true;
}
$recipient = $table->getColumn('recipient');
if ($recipient->getLength() !== 512) {
$recipient->setLength(512);
$modified = true;
}
if ($modified) {
return $schema;
}
}
return null;
}
}
@@ -0,0 +1,110 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2000Date20170707093535 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('spreedme_messages')) {
$table = $schema->createTable('spreedme_messages');
$table->addColumn('id', Types::INTEGER, [
'autoincrement' => true,
'notnull' => true,
'length' => 11,
]);
$table->addColumn('sender', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('recipient', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('sessionId', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('object', Types::TEXT, [
'notnull' => true,
]);
$table->addColumn('timestamp', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->setPrimaryKey(['id']);
}
if (!$schema->hasTable('spreedme_rooms')) {
$table = $schema->createTable('spreedme_rooms');
$table->addColumn('id', Types::INTEGER, [
'autoincrement' => true,
'notnull' => true,
'length' => 11,
]);
$table->addColumn('name', Types::STRING, [
'notnull' => false,
'length' => 255,
'default' => '',
]);
$table->addColumn('token', Types::STRING, [
'notnull' => false,
'length' => 32,
'default' => '',
]);
$table->addColumn('type', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->setPrimaryKey(['id']);
// FIXME: Couldn't make it unique because the migration only ran afterwards on updates
$table->addIndex(['token'], 'unique_token');
}
if (!$schema->hasTable('spreedme_room_participants')) {
$table = $schema->createTable('spreedme_room_participants');
$table->addColumn('userId', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('roomId', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->addColumn('lastPing', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->addColumn('sessionId', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
}
return $schema;
}
}
@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2000Date20171026140256 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
protected IConfig $config,
protected IGroupManager $groupManager,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
if (version_compare($this->config->getAppValue('spreed', 'installed_version', '0.0.0'), '2.0.0', '<')) {
// Migrations only work after 2.0.0
return;
}
$update = $this->connection->getQueryBuilder();
$update->update('spreedme_rooms')
->set('name', $update->createNamedParameter(''))
->where($update->expr()->eq('id', $update->createParameter('room_id')));
$query = $this->connection->getQueryBuilder();
$query->select('*')
->from('spreedme_rooms');
$result = $query->executeQuery();
$output->startProgress();
while ($row = $result->fetch()) {
$output->advance();
if (strlen($row['name']) !== 12 || $this->groupManager->groupExists($row['name'])) {
continue;
}
$update->setParameter('room_id', (int)$row['id'], IQueryBuilder::PARAM_INT)
->executeStatement();
}
$output->finishProgress();
}
}
@@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use OCP\Security\ISecureRandom;
class Version2000Date20171026140257 extends SimpleMigrationStep {
/** @var string[] */
protected array $tokens;
public function __construct(
protected IDBConnection $connection,
protected IConfig $config,
protected ISecureRandom $secureRandom,
) {
$this->tokens = [];
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
if (version_compare($this->config->getAppValue('spreed', 'installed_version', '0.0.0'), '2.0.0', '<')) {
// Migrations only work after 2.0.0
return;
}
$chars = str_replace(['l', '0', '1'], '', ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
$entropy = (int)$this->config->getAppValue('spreed', 'token_entropy', '8');
$update = $this->connection->getQueryBuilder();
$update->update('spreedme_rooms')
->set('token', $update->createParameter('token'))
->where($update->expr()->eq('id', $update->createParameter('room_id')));
$query = $this->connection->getQueryBuilder();
$query->select('*')
->from('spreedme_rooms')
->where($query->expr()->emptyString('token'))
->orWhere($query->expr()->isNull('token'));
$result = $query->executeQuery();
$output->startProgress();
while ($row = $result->fetch()) {
$output->advance();
$token = $this->getNewToken($entropy, $chars);
$update->setParameter('token', $token)
->setParameter('room_id', (int)$row['id'], IQueryBuilder::PARAM_INT)
->executeStatement();
}
$output->finishProgress();
}
/**
* @param int $entropy
* @param string $chars
* @return string
*/
protected function getNewToken(int $entropy, string $chars): string {
$token = $this->secureRandom->generate($entropy, $chars);
while (isset($this->tokens[$token])) {
$token = $this->secureRandom->generate($entropy, $chars);
}
$this->tokens[$token] = $token;
return $token;
}
}
@@ -0,0 +1,143 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCA\Talk\Participant;
use OCA\Talk\Room;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20170707115443 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $db,
protected IConfig $config,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('spreedme_room_participants');
if (!$table->hasColumn('participantType')) {
$table->addColumn('participantType', Types::SMALLINT, [
'notnull' => true,
'length' => 6,
'default' => 0,
]);
}
return $schema;
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
if (version_compare($this->config->getAppValue('spreed', 'installed_version', '0.0.0'), '2.0.0', '<')) {
// Migrations only work after 2.0.0
return;
}
$query = $this->db->getQueryBuilder();
$query->selectAlias($query->createFunction('COUNT(*)'), 'num_rooms')
->from('spreedme_rooms');
$result = $query->executeQuery();
$return = (int)$result->fetch();
$result->closeCursor();
$numRooms = (int)$return['num_rooms'];
if ($numRooms === 0) {
return;
}
$query->select('id')
->from('spreedme_rooms')
->where($query->expr()->eq('type', $query->createNamedParameter(Room::TYPE_ONE_TO_ONE)));
$result = $query->executeQuery();
$one2oneRooms = [];
while ($row = $result->fetch()) {
$one2oneRooms[] = (int)$row['id'];
}
$result->closeCursor();
if (!empty($one2oneRooms)) {
$owners = $this->makeOne2OneParticipantsOwners($one2oneRooms);
$output->info('Made ' . $owners . ' users owner of their one2one calls');
}
if (count($one2oneRooms) !== $numRooms) {
$moderators = $this->makeGroupParticipantsModerators($one2oneRooms);
$output->info('Made ' . $moderators . ' users moderators in group calls');
}
}
/**
* @param int[] $one2oneRooms List of one2one room ids
* @return int Number of updated participants
*/
protected function makeOne2OneParticipantsOwners(array $one2oneRooms): int {
$update = $this->db->getQueryBuilder();
if ($this->db->getDatabaseProvider() !== IDBConnection::PLATFORM_POSTGRES) {
$update->update('spreedme_room_participants')
->set('participantType', $update->createNamedParameter(Participant::OWNER))
->where($update->expr()->in('roomId', $update->createNamedParameter($one2oneRooms, IQueryBuilder::PARAM_INT_ARRAY)));
} else {
$update->update('spreedme_room_participants')
->set('participanttype', $update->createNamedParameter(Participant::OWNER))
->where($update->expr()->in('roomId', $update->createNamedParameter($one2oneRooms, IQueryBuilder::PARAM_INT_ARRAY)));
}
return $update->executeStatement();
}
/**
* @param int[] $one2oneRooms List of one2one room ids which should not be touched
* @return int Number of updated participants
*/
protected function makeGroupParticipantsModerators(array $one2oneRooms): int {
$update = $this->db->getQueryBuilder();
if ($this->db->getDatabaseProvider() !== IDBConnection::PLATFORM_POSTGRES) {
$update->update('spreedme_room_participants')
->set('participantType', $update->createNamedParameter(Participant::MODERATOR))
->where($update->expr()->nonEmptyString('userId'));
} else {
$update->update('spreedme_room_participants')
->set('participanttype', $update->createNamedParameter(Participant::MODERATOR))
->where($update->expr()->nonEmptyString('userId'));
}
if (!empty($one2oneRooms)) {
$update->andWhere($update->expr()->notIn('roomId', $update->createNamedParameter($one2oneRooms, IQueryBuilder::PARAM_INT_ARRAY)));
}
return $update->executeStatement();
}
}
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20170913104501 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('videocalls_signaling')) {
$table = $schema->createTable('videocalls_signaling');
$table->addColumn('sender', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('recipient', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('message', Types::TEXT, [
'notnull' => true,
]);
$table->addColumn('timestamp', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->addIndex(['recipient', 'timestamp'], 'vcsig_recipient');
}
if ($schema->hasTable('spreedme_messages')) {
$schema->dropTable('spreedme_messages');
}
return $schema;
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20170921145301 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('spreedme_rooms');
$table->addColumn('password', Types::STRING, [
'notnull' => false,
'length' => 255,
'default' => '',
]);
return $schema;
}
}
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\IConfig;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20170929092606 extends SimpleMigrationStep {
public function __construct(
protected IConfig $config,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
$stunServer = $this->config->getAppValue('spreed', 'stun_server', 'stun.nextcloud.com:443');
$turnServer = [
'server' => $this->config->getAppValue('spreed', 'turn_server'),
'secret' => $this->config->getAppValue('spreed', 'turn_server_secret'),
'protocols' => $this->config->getAppValue('spreed', 'turn_server_protocols'),
];
$this->config->setAppValue('spreed', 'stun_servers', json_encode([$stunServer]));
if ($turnServer['server'] !== '' && $turnServer['secret'] !== '' && $turnServer['protocols'] !== '') {
$this->config->setAppValue('spreed', 'turn_servers', json_encode([$turnServer]));
}
$this->config->deleteAppValue('spreed', 'stun_server');
$this->config->deleteAppValue('spreed', 'turn_server');
$this->config->deleteAppValue('spreed', 'turn_server_secret');
$this->config->deleteAppValue('spreed', 'turn_server_protocols');
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20171009132424 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('spreedme_rooms');
$table->addColumn('activeSince', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('activeGuests', Types::INTEGER, [
'notnull' => true,
'length' => 4,
'default' => 0,
'unsigned' => true,
]);
return $schema;
}
}
@@ -0,0 +1,390 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Doctrine\DBAL\Exception\InvalidFieldNameException;
use Doctrine\DBAL\Exception\TableNotFoundException;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20171026134605 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
protected IConfig $config,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
/**
* Table had to be rebuild because it was missing a primary key
* @see Version11000Date20201209142525
*
* if (!$schema->hasTable('talk_signaling')) {
* $table = $schema->createTable('talk_signaling');
*
* $table->addColumn('sender', Types::STRING, [
* 'notnull' => true,
* 'length' => 255,
* ]);
* $table->addColumn('recipient', Types::STRING, [
* 'notnull' => true,
* 'length' => 255,
* ]);
* $table->addColumn('message', Types::TEXT, [
* 'notnull' => true,
* ]);
* $table->addColumn('timestamp', Types::INTEGER, [
* 'notnull' => true,
* 'length' => 11,
* ]);
*
* $table->addIndex(['recipient', 'timestamp'], 'ts_recipient_time');
* }
*/
if (!$schema->hasTable('talk_rooms')) {
$table = $schema->createTable('talk_rooms');
$table->addColumn('id', Types::INTEGER, [
'autoincrement' => true,
'notnull' => true,
'length' => 11,
]);
$table->addColumn('name', Types::STRING, [
'notnull' => false,
'length' => 255,
'default' => '',
]);
$table->addColumn('token', Types::STRING, [
'notnull' => false,
'length' => 32,
'default' => '',
]);
$table->addColumn('type', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->addColumn('password', Types::STRING, [
'notnull' => false,
'length' => 255,
'default' => '',
]);
$table->addColumn('activeSince', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('activeGuests', Types::INTEGER, [
'notnull' => true,
'length' => 4,
'default' => 0,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['token'], 'tr_room_token');
}
if (!$schema->hasTable('talk_participants')) {
$table = $schema->createTable('talk_participants');
$table->addColumn('userId', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('roomId', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->addColumn('lastPing', Types::INTEGER, [
'notnull' => true,
'length' => 11,
]);
$table->addColumn('sessionId', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('participantType', Types::SMALLINT, [
'notnull' => true,
'length' => 6,
'default' => 0,
]);
}
return $schema;
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
if (version_compare($this->config->getAppValue('spreed', 'installed_version', '0.0.0'), '2.0.0', '<')) {
// Migrations only work after 2.0.0
return;
}
$roomIdMap = $this->copyRooms();
$this->copyParticipants($roomIdMap);
$this->fixNotifications($roomIdMap);
$this->fixActivities($roomIdMap);
$this->fixActivityMails($roomIdMap);
}
/**
* @return int[]
*/
protected function copyRooms(): array {
$roomIdMap = [];
$insert = $this->connection->getQueryBuilder();
$insert->insert('talk_rooms')
->values([
'name' => $insert->createParameter('name'),
'token' => $insert->createParameter('token'),
'type' => $insert->createParameter('type'),
'password' => $insert->createParameter('password'),
]);
$query = $this->connection->getQueryBuilder();
$query->select('*')
->from('spreedme_rooms');
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$insert
->setParameter('name', $row['name'])
->setParameter('token', $row['token'])
->setParameter('type', (int)$row['type'], IQueryBuilder::PARAM_INT)
->setParameter('password', $row['password']);
$insert->executeStatement();
$roomIdMap[(int)$row['id']] = $insert->getLastInsertId();
}
$result->closeCursor();
return $roomIdMap;
}
/**
* @param int[] $roomIdMap
*/
protected function copyParticipants(array $roomIdMap): void {
$insert = $this->connection->getQueryBuilder();
if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_POSTGRES) {
$insert->insert('talk_participants')
->values([
'userId' => $insert->createParameter('userId'),
'roomId' => $insert->createParameter('roomId'),
'lastPing' => $insert->createParameter('lastPing'),
'sessionId' => $insert->createParameter('sessionId'),
'participantType' => $insert->createParameter('participantType'),
]);
} else {
$insert->insert('talk_participants')
->values([
'userid' => $insert->createParameter('userId'),
'roomid' => $insert->createParameter('roomId'),
'lastping' => $insert->createParameter('lastPing'),
'sessionid' => $insert->createParameter('sessionId'),
'participanttype' => $insert->createParameter('participantType'),
]);
}
$query = $this->connection->getQueryBuilder();
$query->select('*')
->from('spreedme_room_participants');
$result = $query->executeQuery();
while ($row = $result->fetch()) {
if (!isset($roomIdMap[(int)$row['roomId']])) {
continue;
}
$insert
->setParameter('userId', $row['userId'])
->setParameter('roomId', $roomIdMap[(int)$row['roomId']], IQueryBuilder::PARAM_INT)
->setParameter('lastPing', (int)$row['lastPing'], IQueryBuilder::PARAM_INT)
->setParameter('sessionId', $row['sessionId'])
;
if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_POSTGRES) {
$insert->setParameter('participantType', (int)$row['participantType'], IQueryBuilder::PARAM_INT);
} else {
$insert->setParameter('participantType', (int)$row['participanttype'], IQueryBuilder::PARAM_INT);
}
$insert->executeStatement();
}
$result->closeCursor();
}
/**
* @param int[] $roomIdMap
*/
protected function fixNotifications(array $roomIdMap): void {
$update = $this->connection->getQueryBuilder();
$update->update('notifications')
->set('object_id', $update->createParameter('newId'))
->where($update->expr()->eq('notification_id', $update->createParameter('id')));
$delete = $this->connection->getQueryBuilder();
$delete->delete('notifications')
->where($delete->expr()->eq('notification_id', $delete->createParameter('id')));
$query = $this->connection->getQueryBuilder();
$query->select(['notification_id', 'object_id'])
->from('notifications')
->where($query->expr()->eq('app', $query->createNamedParameter('spreed')))
->andWhere($query->expr()->eq('object_type', $query->createNamedParameter('room')));
try {
$result = $query->executeQuery();
} catch (TableNotFoundException $e) {
return;
}
while ($row = $result->fetch()) {
if (!isset($roomIdMap[(int)$row['object_id']])) {
$delete
->setParameter('id', (int)$row['notification_id'])
;
$delete->executeStatement();
continue;
}
$update
->setParameter('id', (int)$row['notification_id'])
->setParameter('newId', $roomIdMap[(int)$row['object_id']])
;
$update->executeStatement();
}
$result->closeCursor();
}
/**
* @param int[] $roomIdMap
*/
protected function fixActivities(array $roomIdMap): void {
$update = $this->connection->getQueryBuilder();
$update->update('activity')
->set('object_id', $update->createParameter('newId'))
->set('subjectparams', $update->createParameter('subjectParams'))
->where($update->expr()->eq('activity_id', $update->createParameter('id')));
$delete = $this->connection->getQueryBuilder();
$delete->delete('activity')
->where($delete->expr()->eq('activity_id', $delete->createParameter('id')));
$query = $this->connection->getQueryBuilder();
$query->select(['activity_id', 'object_id', 'subjectparams'])
->from('activity')
->where($query->expr()->eq('app', $query->createNamedParameter('spreed')))
->andWhere($query->expr()->eq('type', $query->createNamedParameter('spreed')))
->andWhere($query->expr()->eq('object_type', $query->createNamedParameter('room')));
try {
$result = $query->executeQuery();
} catch (TableNotFoundException|InvalidFieldNameException) {
return;
}
while ($row = $result->fetch()) {
if (!isset($roomIdMap[(int)$row['object_id']])) {
$delete
->setParameter('id', (int)$row['activity_id'])
;
$delete->executeStatement();
continue;
}
$params = json_decode($row['subjectparams'], true);
if (!isset($params['room'])) {
$delete
->setParameter('id', (int)$row['activity_id'])
;
$delete->executeStatement();
continue;
}
$params['room'] = $roomIdMap[(int)$row['object_id']];
$update
->setParameter('id', (int)$row['activity_id'])
->setParameter('newId', $roomIdMap[(int)$row['object_id']])
->setParameter('subjectParams', json_encode($params))
;
$update->executeStatement();
}
$result->closeCursor();
}
/**
* @param int[] $roomIdMap
*/
protected function fixActivityMails(array $roomIdMap): void {
$update = $this->connection->getQueryBuilder();
$update->update('activity_mq')
->set('amq_subjectparams', $update->createParameter('subjectParams'))
->where($update->expr()->eq('mail_id', $update->createParameter('id')));
$delete = $this->connection->getQueryBuilder();
$delete->delete('activity_mq')
->where($delete->expr()->eq('mail_id', $delete->createParameter('id')));
$query = $this->connection->getQueryBuilder();
$query->select(['mail_id', 'amq_subjectparams'])
->from('activity_mq')
->where($query->expr()->eq('amq_appid', $query->createNamedParameter('spreed')))
->andWhere($query->expr()->eq('amq_type', $query->createNamedParameter('spreed')));
try {
$result = $query->executeQuery();
} catch (TableNotFoundException|InvalidFieldNameException) {
return;
}
while ($row = $result->fetch()) {
$params = json_decode($row['subjectparams'], true);
if (!isset($params['room']) || !isset($roomIdMap[(int)$params['room']])) {
$delete
->setParameter('id', (int)$row['mail_id'])
;
$delete->executeStatement();
continue;
}
$params['room'] = $roomIdMap[(int)$params['room']];
$update
->setParameter('id', (int)$row['mail_id'])
->setParameter('subjectParams', json_encode($params))
;
$update->executeStatement();
}
$result->closeCursor();
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20171026141336 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('videocalls_signaling')) {
$schema->dropTable('videocalls_signaling');
}
if ($schema->hasTable('spreedme_rooms')) {
$schema->dropTable('spreedme_rooms');
}
if ($schema->hasTable('spreedme_room_participants')) {
$schema->dropTable('spreedme_room_participants');
}
return $schema;
}
}
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20171031102049 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
$table->addColumn('inCall', Types::BOOLEAN, [
'default' => 0,
]);
return $schema;
}
}
@@ -0,0 +1,137 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20180103144447 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
protected IConfig $config,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('active_since')) {
$table->addColumn('active_since', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('active_guests', Types::INTEGER, [
'notnull' => true,
'length' => 4,
'default' => 0,
'unsigned' => true,
]);
}
$table = $schema->getTable('talk_participants');
if (!$table->hasColumn('user_id')) {
$table->addColumn('user_id', Types::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('room_id', Types::INTEGER, [
'notnull' => true,
'length' => 11,
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('last_ping', Types::INTEGER, [
'notnull' => true,
'length' => 11,
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('session_id', Types::STRING, [
'notnull' => true,
'length' => 255,
'default' => '0',
]);
$table->addColumn('participant_type', Types::SMALLINT, [
'notnull' => true,
'length' => 6,
'default' => 0,
'unsigned' => true,
]);
$table->addColumn('in_call', Types::BOOLEAN, [
'default' => 0,
]);
}
return $schema;
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
if (version_compare($this->config->getAppValue('spreed', 'installed_version', '0.0.0'), '2.0.0', '<')) {
// Migrations only work after 2.0.0
return;
}
if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_POSTGRES) {
$update = $this->connection->getQueryBuilder();
$update->update('talk_rooms')
->set('active_since', 'activeSince')
->set('active_guests', 'activeGuests');
$update->executeStatement();
$update = $this->connection->getQueryBuilder();
$update->update('talk_participants')
->set('user_id', 'userId')
->set('room_id', 'roomId')
->set('last_ping', 'lastPing')
->set('session_id', 'sessionId')
->set('participant_type', 'participantType')
->set('in_call', 'inCall');
$update->executeStatement();
} else {
$update = $this->connection->getQueryBuilder();
$update->update('talk_rooms')
->set('active_since', 'activesince')
->set('active_guests', 'activeguests');
$update->executeStatement();
$update = $this->connection->getQueryBuilder();
$update->update('talk_participants')
->set('user_id', 'userid')
->set('room_id', 'roomid')
->set('last_ping', 'lastping')
->set('session_id', 'sessionid')
->set('participant_type', 'participanttype')
->set('in_call', 'incall');
$update->executeStatement();
}
}
}
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version2001Date20180103150836 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if ($table->hasColumn('activeSince')) {
$table->dropColumn('activeSince');
$table->dropColumn('activeGuests');
}
$table = $schema->getTable('talk_participants');
if ($table->hasColumn('userId')) {
$table->dropColumn('userId');
$table->dropColumn('roomId');
$table->dropColumn('lastPing');
$table->dropColumn('sessionId');
$table->dropColumn('participantType');
$table->dropColumn('inCall');
}
return $schema;
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version21000Date20240919222538 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('archived')) {
$table->addColumn('archived', Types::BOOLEAN, [
'default' => 0,
'notnull' => false,
]);
}
return $schema;
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version21001Date20250328123156 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('important')) {
$table->addColumn('important', Types::BOOLEAN, [
'default' => 0,
'notnull' => false,
]);
}
return $schema;
}
}
@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version21001Date20250417141337 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_phone_numbers')) {
return null;
}
$table = $schema->createTable('talk_phone_numbers');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('phone_number', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('actor_id', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['phone_number']);
$table->addIndex(['actor_id']);
return $schema;
}
}
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version21001Date20250509153510 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('sensitive')) {
$table->addColumn('sensitive', Types::BOOLEAN, [
'default' => 0,
'notnull' => false,
]);
}
return $schema;
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version22000Date20250526102909 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if ($table->hasColumn('active_guests')) {
$table->dropColumn('active_guests');
}
return $schema;
}
}
@@ -0,0 +1,132 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCA\Talk\Participant;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use Override;
class Version22000Date20250623142327 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_threads')) {
return null;
}
$table = $schema->createTable('talk_threads');
$table->addColumn('id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
]);
$table->addColumn('room_id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
]);
$table->addColumn('last_message_id', Types::BIGINT, [
'default' => 0,
'length' => 20,
]);
$table->addColumn('num_replies', Types::BIGINT, [
'default' => 0,
'length' => 20,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['room_id'], 'tt_room_threads');
$table = $schema->createTable('talk_thread_attendees');
$table->addColumn('id', Types::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('room_id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
]);
$table->addColumn('thread_id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
]);
$table->addColumn('attendee_id', Types::BIGINT, [
'notnull' => true,
'length' => 20,
]);
$table->addColumn('actor_type', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('actor_id', Types::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('notification_level', Types::INTEGER, [
'notnull' => false,
'default' => Participant::NOTIFY_DEFAULT,
]);
$table->addColumn('last_read_message', Types::BIGINT, [
'notnull' => false,
'default' => 0,
]);
$table->addColumn('last_mention_message', Types::BIGINT, [
'notnull' => false,
'default' => 0,
]);
$table->addColumn('last_mention_direct', Types::BIGINT, [
'notnull' => false,
'default' => 0,
]);
$table->addColumn('read_privacy', Types::SMALLINT, [
'notnull' => false,
'default' => 0,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
/** Replaced by @see Version22001Date20250927174738 */
// $table->addUniqueIndex(['thread_id', 'actor_type', 'actor_id'], 'tta_thread_attendee');
$table->addIndex(['room_id', 'actor_type', 'actor_id'], 'tta_room_attendee');
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('has_unread_threads')) {
$table->addColumn('has_unread_threads', Types::BOOLEAN, [
'default' => 0,
'notnull' => false,
]);
}
if (!$table->hasColumn('has_unread_thread_mentions')) {
$table->addColumn('has_unread_thread_mentions', Types::BOOLEAN, [
'default' => 0,
'notnull' => false,
]);
}
if (!$table->hasColumn('has_unread_thread_directs')) {
$table->addColumn('has_unread_thread_directs', Types::BOOLEAN, [
'default' => 0,
'notnull' => false,
]);
}
return $schema;
}
}
@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use Override;
/**
* Add the last activity (for sorting) and thread name for future feature to name a thread
*/
class Version22000Date20250710124258 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_threads');
if (!$table->hasColumn('last_activity')) {
$table->addColumn('last_activity', Types::DATETIME, [
'notnull' => false,
]);
$table->addColumn('name', Types::STRING, [
'notnull' => false,
'length' => 255,
'default' => '',
]);
$table->addIndex(['last_activity'], 'talkthread_lastactive');
}
$table = $schema->getTable('talk_thread_attendees');
if ($table->hasColumn('last_read_message')) {
$table->dropColumn('last_read_message');
}
if ($table->hasColumn('last_mention_message')) {
$table->dropColumn('last_mention_message');
}
if ($table->hasColumn('last_mention_direct')) {
$table->dropColumn('last_mention_direct');
}
if ($table->hasColumn('read_privacy')) {
$table->dropColumn('read_privacy');
}
return $schema;
}
}
@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\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 OCP\Share\IShare;
use Override;
/**
* Add column on rooms if they have at least one attachment
*/
class Version22000Date20250803160923 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $db,
) {
}
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('has_attachments')) {
$table->addColumn('has_attachments', Types::SMALLINT, [
'notnull' => false,
'default' => 0,
]);
return $schema;
}
return null;
}
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
*/
#[Override]
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
$query = $this->db->getQueryBuilder();
$query->select('share_with')
->from('share')
->where($query->expr()->eq('share_type', $query->createNamedParameter(IShare::TYPE_ROOM)))
->groupBy('share_with');
$tokens = [];
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$tokens[] = $row['share_with'];
}
$result->closeCursor();
// Update current conversations with the correct flag
$chunks = array_chunk($tokens, 1000);
$update = $this->db->getQueryBuilder();
$update->update('talk_rooms')
/** Can not use @see \OCA\Talk\Model\Attachment::ATTACHMENTS_ATLEAST_ONE during update */
->set('has_attachments', $update->createNamedParameter(1))
->where($update->expr()->in('token', $update->createParameter('tokens')));
foreach ($chunks as $chunk) {
$update->setParameter('tokens', $chunk, IQueryBuilder::PARAM_STR_ARRAY);
$update->executeStatement();
}
}
}
@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version22000Date20250813122342 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('transcription_language')) {
$table->addColumn('transcription_language', Types::STRING, [
'notnull' => false,
'default' => '',
'length' => 16,
]);
}
return $schema;
}
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use Override;
class Version22001Date20250927174738 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
#[Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_thread_attendees');
if ($table->hasUniqueConstraint('tta_thread_attendee')) {
$table->removeUniqueConstraint('tta_thread_attendee');
}
if (!$table->hasUniqueConstraint('tta_throom_attendee')) {
$table->addUniqueIndex(['thread_id', 'room_id', 'actor_type', 'actor_id'], 'tta_throom_attendee');
}
return null;
}
}
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version3002Date20180319104030 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/**
* The table had to be redone so it contains a primary key
* @see Version11000Date20201209142525
*
* $schema = $schemaClosure();
*
* if (!$schema->hasTable('talk_guests')) {
* $table = $schema->createTable('talk_guests');
*
* $table->addColumn('session_hash', Type::STRING, [
* 'notnull' => false,
* 'length' => 64,
* ]);
* $table->addColumn('display_name', Type::STRING, [
* 'notnull' => false,
* 'length' => 64,
* 'default' => '',
* ]);
*
* $table->addUniqueIndex(['session_hash'], 'tg_session_hash');
* }
*
* return $schema;
*/
return null;
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version3003Date20180707222130 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
if (!$table->hasColumn('favorite')) {
$table->addColumn('favorite', Types::BOOLEAN, [
'default' => 0,
]);
}
return $schema;
}
}
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version3003Date20180718112436 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('last_activity')) {
$table->addColumn('last_activity', Types::DATETIME, [
'notnull' => false,
]);
$table->addIndex(['last_activity'], 'last_active');
}
return $schema;
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
$update = $this->connection->getQueryBuilder();
$update->update('talk_rooms')
->set('last_activity', $update->createParameter('activity'))
->where($update->expr()->eq('id', $update->createParameter('room')));
$query = $this->connection->getQueryBuilder();
$query->select('object_id')
->selectAlias($query->createFunction('MAX(' . $query->getColumnName('creation_timestamp') . ')'), 'last_activity')
->from('comments')
->where($query->expr()->eq('object_type', $query->createNamedParameter('chat')))
->groupBy('object_id');
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$lastActivity = new \DateTime($row['last_activity']);
$update->setParameter('activity', $lastActivity, IQueryBuilder::PARAM_DATE)
->setParameter('room', $row['object_id']);
$update->executeStatement();
}
$result->closeCursor();
}
}
@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version3003Date20180718133519 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('last_message')) {
$table->addColumn('last_message', Types::BIGINT, [
'notnull' => false,
'default' => 0,
]);
}
return $schema;
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
$update = $this->connection->getQueryBuilder();
$update->update('talk_rooms')
->set('last_message', $update->createParameter('message'))
->where($update->expr()->eq('id', $update->createParameter('room')));
$query = $this->connection->getQueryBuilder();
$query->selectAlias($query->createFunction('MAX(' . $query->getColumnName('id') . ')'), 'message')
->addSelect('object_id')
->from('comments')
->where($query->expr()->eq('object_type', $query->createNamedParameter('chat')))
->groupBy('object_id');
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$update->setParameter('message', $row['message'])
->setParameter('room', $row['object_id']);
$update->executeStatement();
}
$result->closeCursor();
}
}
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version3003Date20180720162342 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('object_type')) {
$table->addColumn('object_type', Types::STRING, [
'notnull' => false,
'length' => 64,
'default' => '',
]);
$table->addColumn('object_id', Types::STRING, [
'notnull' => false,
'length' => 64,
'default' => '',
]);
$table->addIndex(['object_type', 'object_id'], 'tr_room_object');
}
return $schema;
}
}
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version3003Date20180722152733 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
$table->dropColumn('in_call');
return $schema;
}
}
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version3003Date20180722152849 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
$table->addColumn('in_call', Types::INTEGER, [
'default' => 0,
]);
return $schema;
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version3003Date20180730080327 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
if (!$table->hasColumn('last_mention')) {
$table->addColumn('last_mention', Types::DATETIME, [
'notnull' => false,
]);
}
return $schema;
}
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCA\Talk\Participant;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version4099Date20181001123058 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
if (!$table->hasColumn('notification_level')) {
$table->addColumn('notification_level', Types::INTEGER, [
'default' => Participant::NOTIFY_DEFAULT,
'notnull' => false,
]);
}
return $schema;
}
}
@@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version5099Date20190121102337 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('talk_commands')) {
$table = $schema->createTable('talk_commands');
$table->addColumn('id', Types::INTEGER, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
]);
$table->addColumn('app', Types::STRING, [
'notnull' => false,
'length' => 64,
'default' => '',
]);
$table->addColumn('name', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('command', Types::STRING, [
'notnull' => true,
'length' => 64,
]);
$table->addColumn('script', Types::TEXT, [
'notnull' => true,
]);
$table->addColumn('response', Types::INTEGER, [
'notnull' => true,
'length' => 6,
'default' => 1,
]);
$table->addColumn('enabled', Types::INTEGER, [
'notnull' => true,
'length' => 6,
'default' => 1,
]);
$table->setPrimaryKey(['id']);
}
return $schema;
}
}
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version5099Date20190319134820 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_rooms')) {
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('read_only')) {
$table->addColumn('read_only', Types::INTEGER, [
'notnull' => true,
'length' => 6,
'default' => 0,
]);
}
}
return $schema;
}
}
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version6099Date20190627172429 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('talk_rooms')) {
$table = $schema->getTable('talk_rooms');
if (!$table->hasColumn('lobby_state')) {
$table->addColumn('lobby_state', Types::INTEGER, [
'notnull' => true,
'length' => 6,
'default' => 0,
]);
$table->addColumn('lobby_timer', Types::DATETIME, [
'notnull' => false,
]);
}
}
return $schema;
}
}
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version7000Date20190717141457 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
if (!$table->hasColumn('last_joined_call')) {
$table->addColumn('last_joined_call', Types::DATETIME, [
'notnull' => false,
]);
}
return $schema;
}
}
@@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Doctrine\DBAL\Schema\SchemaException;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\Types;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version7000Date20190724121136 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @throws SchemaException
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
if (!$table->hasColumn('last_read_message')) {
$table->addColumn('last_read_message', Types::BIGINT, [
'default' => 0,
'notnull' => false,
]);
$table->addColumn('last_mention_message', Types::BIGINT, [
'default' => 0,
'notnull' => false,
]);
}
return $schema;
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @since 13.0.0
*
* @return void
*/
#[\Override]
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
$query = $this->connection->getQueryBuilder();
$query->select('m.user_id', 'm.object_id')
->selectAlias($query->createFunction('MAX(' . $query->getColumnName('c.id') . ')'), 'last_comment')
->from('comments_read_markers', 'm')
->leftJoin('m', 'comments', 'c', $query->expr()->andX(
$query->expr()->eq('c.object_id', 'm.object_id'),
$query->expr()->eq('c.object_type', 'm.object_type'),
$query->expr()->eq('c.creation_timestamp', 'm.marker_datetime')
))
->where($query->expr()->eq('m.object_type', $query->createNamedParameter('chat')))
->groupBy('m.user_id', 'm.object_id');
$update = $this->connection->getQueryBuilder();
$update->update('talk_participants')
->set('last_read_message', $update->createParameter('message_id'))
->where($update->expr()->eq('user_id', $update->createParameter('user_id')))
->andWhere($update->expr()->eq('room_id', $update->createParameter('room_id')));
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$update->setParameter('message_id', (int)$row['last_comment'], IQueryBuilder::PARAM_INT)
->setParameter('user_id', $row['user_id'])
->setParameter('room_id', (int)$row['object_id'], IQueryBuilder::PARAM_INT);
$update->executeStatement();
}
$result->closeCursor();
/**
* The above query only works if the user read in the same exact second
* as the comment was posted (author only), we set the read marker to -1
* for all users and in case of -1 we calculate the marker on the next request.
*/
$update = $this->connection->getQueryBuilder();
$update->update('talk_participants')
->set('last_read_message', $update->createNamedParameter(-1))
->where($update->expr()->isNotNull('user_id'))
->andWhere($update->expr()->eq('last_read_message', $update->createNamedParameter(0)));
$update->executeStatement();
}
}
@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Doctrine\DBAL\Schema\SchemaException;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version7000Date20190724121137 extends SimpleMigrationStep {
public function __construct(
protected IDBConnection $connection,
) {
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @since 13.0.0
*/
#[\Override]
public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options): void {
$query = $this->connection->getQueryBuilder();
$query->select('p.user_id', 'p.room_id')
->selectAlias($query->createFunction('MAX(' . $query->getColumnName('c.id') . ')'), 'last_mention_message')
->from('talk_participants', 'p')
->leftJoin('p', 'comments', 'c', $query->expr()->andX(
$query->expr()->eq('c.object_id', $query->expr()->castColumn('p.room_id', IQueryBuilder::PARAM_STR)),
$query->expr()->eq('c.object_type', $query->createNamedParameter('chat')),
$query->expr()->eq('c.creation_timestamp', 'p.last_mention')
))
->where($query->expr()->isNotNull('p.user_id'))
->groupBy('p.user_id', 'p.room_id');
$update = $this->connection->getQueryBuilder();
$update->update('talk_participants')
->set('last_mention_message', $update->createParameter('message_id'))
->where($update->expr()->eq('user_id', $update->createParameter('user_id')))
->andWhere($update->expr()->eq('room_id', $update->createParameter('room_id')));
$result = $query->executeQuery();
while ($row = $result->fetch()) {
$update->setParameter('message_id', (int)$row['last_mention_message'], IQueryBuilder::PARAM_INT)
->setParameter('user_id', $row['user_id'])
->setParameter('room_id', (int)$row['room_id'], IQueryBuilder::PARAM_INT);
$update->executeStatement();
}
$result->closeCursor();
}
/**
* @param IOutput $output
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
* @throws SchemaException
* @since 13.0.0
*/
#[\Override]
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
if ($table->hasColumn('last_mention')) {
$table->dropColumn('last_mention');
}
return $schema;
}
}
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Talk\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version8000Date20200331144101 extends SimpleMigrationStep {
#[\Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_participants');
if (!$table->hasIndex('tp_ident')) {
$table->addUniqueIndex(['room_id', 'user_id', 'session_id'], 'tp_ident');
}
if (!$table->hasIndex('tp_room')) {
$table->addIndex(['room_id'], 'tp_room');
}
if (!$table->hasIndex('tp_last_ping')) {
$table->addIndex(['last_ping'], 'tp_last_ping');
}
if (!$table->hasIndex('tp_in_call')) {
$table->addIndex(['in_call'], 'tp_in_call');
}
return $schema;
}
}

Some files were not shown because too many files have changed in this diff Show More