Skip to content

Commit

Permalink
fix(GODT-3183): Fix mailbox flags tables
Browse files Browse the repository at this point in the history
Ensure combined primary keys start with the mailbox id then the flag
value and correct the data type to integer.
  • Loading branch information
LBeernaertProton committed Dec 29, 2023
1 parent 4169b08 commit 759b010
Showing 1 changed file with 129 additions and 0 deletions.
129 changes: 129 additions & 0 deletions internal/db_impl/sqlite3/v3/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,100 @@ import (

type Migration struct{}

const MailboxFlagsTableNameTmp = "tmp_mailbox_flags"

const MailboxPermFlagsTableNameTmp = "tmp_mailbox_perm_flags"

const MailboxAttrsTableNameTmp = "tmp_mailbox_attr"

func (m Migration) Run(ctx context.Context, tx utils.QueryWrapper, _ imap.UIDValidityGenerator) error {
// Create mailboxes flags table.
{
query := fmt.Sprintf("CREATE TABLE `%[1]v` (`%[3]v` integer NOT NULL, `%[2]v` text NOT NULL, "+
"CONSTRAINT `mailbox_flags_mailbox_id` FOREIGN KEY (`%[3]v`) REFERENCES `%[4]v` (`%[5]v`) ON DELETE CASCADE, "+
"PRIMARY KEY (%[2]v, %[3]v)"+
")",
MailboxFlagsTableNameTmp,
v1.MailboxFlagsFieldValue,
v1.MailboxFlagsFieldMailboxID,
v1.MailboxesTableName,
v1.MailboxesFieldID,
)

if _, err := utils.ExecQuery(ctx, tx, query); err != nil {
return fmt.Errorf("failed to create mailboxes flags table: %w", err)
}

if err := migrateMailboxFlags(
ctx,
tx,
v1.MailboxFlagsTableName,
MailboxFlagsTableNameTmp,
v1.MailboxFlagsFieldMailboxID,
v1.MailboxFlagsFieldValue,
); err != nil {
return fmt.Errorf("failed to migrate mailbox flags table: %w", err)
}
}

// Create perm mailboxes flags table.
{
query := fmt.Sprintf("CREATE TABLE `%[1]v` (`%[3]v` integer NOT NULL, `%[2]v` text NOT NULL, "+
"CONSTRAINT `perm_mailbox_flags_mailbox_id` FOREIGN KEY (`%[3]v`) REFERENCES `%[4]v` (`%[5]v`) ON DELETE CASCADE, "+
"PRIMARY KEY (%[2]v, %[3]v)"+
")",
MailboxPermFlagsTableNameTmp,
v1.MailboxPermFlagsFieldValue,
v1.MailboxPermFlagsFieldMailboxID,
v1.MailboxesTableName,
v1.MailboxesFieldID,
)

if _, err := utils.ExecQuery(ctx, tx, query); err != nil {
return fmt.Errorf("failed to create mailboxes perm flags table: %w", err)
}

if err := migrateMailboxFlags(
ctx,
tx,
v1.MailboxPermFlagsTableName,
MailboxPermFlagsTableNameTmp,
v1.MailboxPermFlagsFieldMailboxID,
v1.MailboxPermFlagsFieldValue,
); err != nil {
return fmt.Errorf("failed to migrate mailbox perm flags table: %w", err)
}
}

// Create Mailbox Attributes table.
{
query := fmt.Sprintf("CREATE TABLE `%[1]v` (`%[3]v` integer NOT NULL, `%[2]v` text NOT NULL, "+
"CONSTRAINT `perm_attrs_flags_mailbox_id` FOREIGN KEY (`%[3]v`) REFERENCES `%[4]v` (`%[5]v`) ON DELETE CASCADE, "+
"PRIMARY KEY (%[2]v, %[3]v)"+
")",
MailboxAttrsTableNameTmp,
v1.MailboxAttrsFieldValue,
v1.MailboxAttrsFieldMailboxID,
v1.MailboxesTableName,
v1.MailboxesFieldID,
)

if _, err := utils.ExecQuery(ctx, tx, query); err != nil {
return fmt.Errorf("failed to create mailboxes attr table: %w", err)
}

if err := migrateMailboxFlags(
ctx,
tx,
v1.MailboxAttrsTableName,
MailboxAttrsTableNameTmp,
v1.MailboxAttrsFieldMailboxID,
v1.MailboxAttrsFieldValue,
); err != nil {
return fmt.Errorf("failed to migrate mailbox perm flags table: %w", err)
}
}

{
// Create an index on message id field to speed up lookup queries for message flags.
query := fmt.Sprintf("create index message_flags_message_id_index on %v (%v)",
Expand Down Expand Up @@ -62,3 +155,39 @@ func (m Migration) Run(ctx context.Context, tx utils.QueryWrapper, _ imap.UIDVal

return nil
}

func migrateMailboxFlags(ctx context.Context,
tx utils.QueryWrapper,
fromTableName string,
toTableName string,
fieldID string,
fieldValue string,
) error {
query := fmt.Sprintf("INSERT INTO %v (`%v`, `%v`) SELECT `%v`,`%v` FROM %v ORDER BY `%v`",
toTableName,
fieldID,
fieldValue,
fieldID,
fieldValue,
fromTableName,
fieldID,
)

if _, err := utils.ExecQuery(ctx, tx, query); err != nil {
return err
}

dropQuery := fmt.Sprintf("DROP TABLE %v", fromTableName)

if _, err := utils.ExecQuery(ctx, tx, dropQuery); err != nil {
return err
}

renameQuery := fmt.Sprintf("ALTER TABLE %v RENAME TO %v", toTableName, fromTableName)

if _, err := utils.ExecQuery(ctx, tx, renameQuery); err != nil {
return err
}

return nil
}

0 comments on commit 759b010

Please sign in to comment.