Skip to content

Commit 873e34a

Browse files
committed
Add indices, change column types and
change foreign keys to named foreign keys for recipients and attachments Signed-off-by: Anna Larch <anna@nextcloud.com>
1 parent 8d1c960 commit 873e34a

File tree

2 files changed

+154
-81
lines changed

2 files changed

+154
-81
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* @copyright Copyright (c) 2022 Anna Larch <anna.larch@gmx.net>
7+
*
8+
* @author Anna Larch <anna.larch@gmx.net>
9+
*
10+
* @license GNU AGPL version 3 or any later version
11+
*
12+
* This program is free software: you can redistribute it and/or modify
13+
* it under the terms of the GNU Affero General Public License as
14+
* published by the Free Software Foundation, either version 3 of the
15+
* License, or (at your option) any later version.
16+
*
17+
* This program is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU Affero General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU Affero General Public License
23+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24+
*
25+
*/
26+
27+
namespace OCA\Mail\Migration;
28+
29+
use Closure;
30+
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
31+
use Doctrine\DBAL\Schema\Table;
32+
use Doctrine\DBAL\Types\Type;
33+
use OCP\DB\ISchemaWrapper;
34+
use OCP\DB\QueryBuilder\IQueryBuilder;
35+
use OCP\IDBConnection;
36+
use OCP\Migration\IOutput;
37+
use OCP\Migration\SimpleMigrationStep;
38+
39+
class Version1120Date20220412111833 extends SimpleMigrationStep {
40+
/** @var IDBConnection $connection */
41+
private $connection;
42+
43+
public function __construct(IDBConnection $connection) {
44+
$this->connection = $connection;
45+
}
46+
47+
/**
48+
* @param IOutput $output
49+
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
50+
* @param array $options
51+
*/
52+
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
53+
$schema = $schemaClosure();
54+
55+
// Remove old unnamed attachments FK
56+
$attachmentsTable = $schema->getTable('mail_attachments');
57+
$fks = $attachmentsTable->getForeignKeys();
58+
foreach ($fks as $fk) {
59+
$attachmentsTable->removeForeignKey($fk->getName());
60+
}
61+
62+
// Remove old unnamed FK and change primary key type for recipients table
63+
$recipientsTable = $schema->getTable('mail_recipients');
64+
$fks = $recipientsTable->getForeignKeys();
65+
foreach ($fks as $fk) {
66+
$recipientsTable->removeForeignKey($fk->getName());
67+
}
68+
69+
$recipientsTable->changeColumn('id', [
70+
'type' => Type::getType('bigint'),
71+
'length' => 20,
72+
]);
73+
$qb = $this->connection->getQueryBuilder();
74+
$qb->delete('mail_recipients');
75+
$qb->execute();
76+
77+
// Truncate and change primary key type for messages table
78+
$qb1 = $this->connection->getQueryBuilder();
79+
$qb1->delete('mail_messages');
80+
$qb1->execute();
81+
82+
$messagesTable = $schema->getTable('mail_messages');
83+
$messagesTable->changeColumn('id', [
84+
'type' => Type::getType('bigint'),
85+
'length' => 20,
86+
]);
87+
88+
// Truncate message_tags table
89+
$qb2 = $this->connection->getQueryBuilder();
90+
$qb2->delete('mail_message_tags');
91+
$qb2->execute();
92+
93+
// unset all locks for the mailboxes table
94+
$qb3 = $this->connection->getQueryBuilder();
95+
$qb3->update('mail_mailboxes')
96+
->set('sync_new_lock', $qb3->createNamedParameter(null, IQueryBuilder::PARAM_NULL))
97+
->set('sync_changed_lock', $qb3->createNamedParameter(null, IQueryBuilder::PARAM_NULL))
98+
->set('sync_vanished_lock', $qb3->createNamedParameter(null, IQueryBuilder::PARAM_NULL))
99+
->set('sync_new_token', $qb3->createNamedParameter(null, IQueryBuilder::PARAM_NULL))
100+
->set('sync_changed_token', $qb3->createNamedParameter(null, IQueryBuilder::PARAM_NULL))
101+
->set('sync_vanished_token', $qb3->createNamedParameter(null, IQueryBuilder::PARAM_NULL));
102+
$qb3->execute();
103+
}
104+
105+
/**
106+
* @param IOutput $output
107+
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
108+
* @param array $options
109+
* @return null|ISchemaWrapper
110+
*/
111+
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
112+
$schema = $schemaClosure();
113+
114+
// Add new named FKs to attachments and recipients
115+
$recipientsTable = $schema->getTable('mail_recipients');
116+
$recipientsTable->addForeignKeyConstraint($schema->getTable('mail_local_messages'), ['local_message_id'], ['id'], ['onDelete' => 'CASCADE'], 'recipient_local_message');
117+
118+
$attachmentsTable = $schema->getTable('mail_attachments');
119+
$attachmentsTable->addForeignKeyConstraint($schema->getTable('mail_local_messages'), ['local_message_id'], ['id'], ['onDelete' => 'CASCADE'], 'attachment_local_message');
120+
121+
/** @var Table $table */
122+
$table = $schema->getTable('mail_messages');
123+
$table->addIndex(['mailbox_id', 'flag_important', 'flag_deleted', 'flag_seen'], 'mail_messages_id_flags');
124+
$table->addIndex(['mailbox_id', 'flag_deleted', 'flag_flagged'], 'mail_messages_id_flags2');
125+
$table->addIndex(['mailbox_id'], 'mail_messages_mailbox_id');
126+
127+
// Postgres doesn't allow for shortened indices, so let's skip the last index.
128+
if ($schema->getDatabasePlatform() instanceof PostgreSQL94Platform) {
129+
return $schema;
130+
}
131+
132+
$table->addIndex(['mailbox_id', 'thread_root_id', 'sent_at'], 'mail_msg_thrd_root_snt_idx', [], ['lengths' => [null, 64, null]]);
133+
134+
return $schema;
135+
}
136+
}

tests/psalm-baseline.xml

Lines changed: 18 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@
1313
<code>MessageSentEvent</code>
1414
<code>MessageSentEvent</code>
1515
<code>MessageSentEvent</code>
16-
<code>MessageSentEvent</code>
1716
<code>NewMessagesSynchronized</code>
17+
<code>OutboxMessageCreatedEvent</code>
1818
<code>SynchronizationEvent</code>
1919
<code>UserDeletedEvent</code>
20-
<code>OutboxMessageCreatedEvent</code>
2120
</MissingDependency>
2221
<UndefinedClass occurrences="1">
2322
<code>ContainerInterface</code>
@@ -68,11 +67,6 @@
6867
<code>Command</code>
6968
</UndefinedClass>
7069
</file>
71-
<file src="lib/Command/RepairMailTheads.php">
72-
<UndefinedClass occurrences="1">
73-
<code>Command</code>
74-
</UndefinedClass>
75-
</file>
7670
<file src="lib/Command/SyncAccount.php">
7771
<UndefinedClass occurrences="1">
7872
<code>Command</code>
@@ -88,74 +82,15 @@
8882
<code>Command</code>
8983
</UndefinedClass>
9084
</file>
91-
<file src="lib/Db/AliasMapper.php">
92-
<ImplicitToStringCast occurrences="1">
93-
<code>$qb2-&gt;createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)</code>
94-
</ImplicitToStringCast>
95-
</file>
96-
<file src="lib/Db/CollectedAddressMapper.php">
97-
<ImplicitToStringCast occurrences="1">
98-
<code>$qb2-&gt;createParameter('ids')</code>
99-
</ImplicitToStringCast>
100-
</file>
101-
<file src="lib/Db/MailboxMapper.php">
102-
<ImplicitToStringCast occurrences="1">
103-
<code>$qb2-&gt;createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)</code>
104-
</ImplicitToStringCast>
105-
</file>
10685
<file src="lib/Db/MessageMapper.php">
107-
<ImplicitToStringCast occurrences="25">
108-
<code>$deleteMessagesQuery-&gt;createParameter('messageIds')</code>
109-
<code>$deleteRecipientsQuery-&gt;createParameter('ids')</code>
110-
<code>$deleteRecipientsQuery-&gt;createParameter('messageIds')</code>
111-
<code>$messageIdQuery-&gt;createParameter('uids')</code>
112-
<code>$messagesQuery-&gt;createFunction($mailboxesQuery-&gt;getSQL())</code>
113-
<code>$qb-&gt;createFunction($selectMailboxIds-&gt;getSQL())</code>
114-
<code>$qb-&gt;createNamedParameter($mailboxIds, IQueryBuilder::PARAM_INT_ARRAY)</code>
115-
<code>$qb-&gt;createNamedParameter($query-&gt;getBcc(), IQueryBuilder::PARAM_STR_ARRAY)</code>
116-
<code>$qb-&gt;createNamedParameter($query-&gt;getBcc(), IQueryBuilder::PARAM_STR_ARRAY)</code>
117-
<code>$qb-&gt;createNamedParameter($query-&gt;getCc(), IQueryBuilder::PARAM_STR_ARRAY)</code>
118-
<code>$qb-&gt;createNamedParameter($query-&gt;getCc(), IQueryBuilder::PARAM_STR_ARRAY)</code>
119-
<code>$qb-&gt;createNamedParameter($query-&gt;getFrom(), IQueryBuilder::PARAM_STR_ARRAY)</code>
120-
<code>$qb-&gt;createNamedParameter($query-&gt;getFrom(), IQueryBuilder::PARAM_STR_ARRAY)</code>
121-
<code>$qb-&gt;createNamedParameter($query-&gt;getTo(), IQueryBuilder::PARAM_STR_ARRAY)</code>
122-
<code>$qb-&gt;createNamedParameter($query-&gt;getTo(), IQueryBuilder::PARAM_STR_ARRAY)</code>
123-
<code>$qb-&gt;createNamedParameter($uids, IQueryBuilder::PARAM_INT_ARRAY)</code>
124-
<code>$qb-&gt;createParameter('ids')</code>
125-
<code>$qb-&gt;createParameter('uids')</code>
126-
<code>$qb-&gt;createParameter('uids')</code>
127-
<code>$qb2-&gt;createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)</code>
128-
<code>$qb2-&gt;createNamedParameter(array_keys($indexedMessages), IQueryBuilder::PARAM_INT_ARRAY)</code>
129-
<code>$qb4-&gt;createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)</code>
130-
<code>$query-&gt;createParameter('ids')</code>
131-
<code>$select-&gt;createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)</code>
132-
<code>$select-&gt;createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)</code>
133-
</ImplicitToStringCast>
13486
<InvalidReturnStatement occurrences="1">
13587
<code>$update-&gt;execute()</code>
13688
</InvalidReturnStatement>
13789
<InvalidReturnType occurrences="1">
13890
<code>int</code>
13991
</InvalidReturnType>
14092
</file>
141-
<file src="lib/Db/StatisticsDao.php">
142-
<ImplicitToStringCast occurrences="7">
143-
<code>$qb-&gt;createNamedParameter($emails, IQueryBuilder::PARAM_STR_ARRAY)</code>
144-
<code>$qb-&gt;createNamedParameter($emails, IQueryBuilder::PARAM_STR_ARRAY)</code>
145-
<code>$qb-&gt;createNamedParameter($emails, IQueryBuilder::PARAM_STR_ARRAY)</code>
146-
<code>$qb-&gt;createNamedParameter($mailboxIds, IQueryBuilder::PARAM_INT_ARRAY)</code>
147-
<code>$qb-&gt;createNamedParameter($mailboxIds, IQueryBuilder::PARAM_INT_ARRAY)</code>
148-
<code>$qb-&gt;createNamedParameter($mailboxIds, IQueryBuilder::PARAM_INT_ARRAY)</code>
149-
<code>$qb-&gt;createNamedParameter($mailboxIds, IQueryBuilder::PARAM_INT_ARRAY)</code>
150-
</ImplicitToStringCast>
151-
</file>
15293
<file src="lib/Db/TagMapper.php">
153-
<ImplicitToStringCast occurrences="4">
154-
<code>$deleteQB-&gt;createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)</code>
155-
<code>$deleteQB-&gt;createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)</code>
156-
<code>$qb-&gt;createParameter('ids')</code>
157-
<code>$qb-&gt;createParameter('ids')</code>
158-
</ImplicitToStringCast>
15994
<InvalidArgument occurrences="1"/>
16095
</file>
16196
<file src="lib/Events/BeforeMessageDeletedEvent.php">
@@ -198,6 +133,11 @@
198133
<code>Event</code>
199134
</MissingDependency>
200135
</file>
136+
<file src="lib/Events/OutboxMessageCreatedEvent.php">
137+
<MissingDependency occurrences="1">
138+
<code>Event</code>
139+
</MissingDependency>
140+
</file>
201141
<file src="lib/Events/SaveDraftEvent.php">
202142
<MissingDependency occurrences="1">
203143
<code>Event</code>
@@ -298,10 +238,12 @@
298238
<code>UserDeletedListener</code>
299239
</MissingDependency>
300240
</file>
301-
<file src="lib/Migration/Version1105Date20210922104324.php">
302-
<ImplicitToStringCast occurrences="1">
303-
<code>$qb-&gt;createNamedParameter($accountIds, IQueryBuilder::PARAM_INT_ARRAY)</code>
304-
</ImplicitToStringCast>
241+
<file src="lib/Migration/Version1120Date20220412111833.php">
242+
<UndefinedClass occurrences="3">
243+
<code>PostgreSQL94Platform</code>
244+
<code>Type</code>
245+
<code>Type</code>
246+
</UndefinedClass>
305247
</file>
306248
<file src="lib/Service/Classification/ImportanceClassifier.php">
307249
<InvalidScalarArgument occurrences="1">
@@ -336,6 +278,12 @@
336278
<code>SaveDraftEvent</code>
337279
</MissingDependency>
338280
</file>
281+
<file src="lib/Service/OutboxService.php">
282+
<MissingDependency occurrences="2">
283+
<code>OutboxMessageCreatedEvent</code>
284+
<code>OutboxMessageCreatedEvent</code>
285+
</MissingDependency>
286+
</file>
339287
<file src="lib/Service/Sync/ImapToDbSynchronizer.php">
340288
<MissingDependency occurrences="4">
341289
<code>NewMessagesSynchronized</code>
@@ -361,15 +309,4 @@
361309
<code>OutputInterface</code>
362310
</UndefinedDocblockClass>
363311
</file>
364-
<file src="lib/Events/OutboxMessageCreatedEvent.php">
365-
<MissingDependency occurrences="1">
366-
<code>Event</code>
367-
</MissingDependency>
368-
</file>
369-
<file src="lib/Service/OutboxService.php">
370-
<MissingDependency occurrences="2">
371-
<code>OutboxMessageCreatedEvent</code>
372-
<code>OutboxMessageCreatedEvent</code>
373-
</MissingDependency>
374-
</file>
375312
</files>

0 commit comments

Comments
 (0)