Skip to content

Commit

Permalink
fix(GODT-2522): Handle invalid message flag migration
Browse files Browse the repository at this point in the history
The first db schema could end up with unresolved references that were
never corrected. These can cause migration to fail. Adjust migration
code to ignore these.
  • Loading branch information
LBeernaertProton committed Jun 28, 2023
1 parent 80c05f8 commit 52391e3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 2 deletions.
40 changes: 40 additions & 0 deletions internal/db_impl/sqlite3/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,16 @@ func prepareV0Database(t *testing.T, dir, user string, testData *testData, uidGe
}

require.NoError(t, utils.ExecQueryAndCheckUpdatedNotZero(ctx, qw, query, args...))

// Insert some flags that reference no mailbox.
{
query := fmt.Sprintf("INSERT INTO %v (`%v`) VALUES ('\\Unrer2'), ('\\Unref1')",
v0.MailboxFlagsTableName,
v0.MailboxFlagsFieldValue,
)

require.NoError(t, utils.ExecQueryAndCheckUpdatedNotZero(ctx, qw, query))
}
}
// Perm flags.
for _, m := range testData.mailboxes {
Expand All @@ -383,6 +393,16 @@ func prepareV0Database(t *testing.T, dir, user string, testData *testData, uidGe
}

require.NoError(t, utils.ExecQueryAndCheckUpdatedNotZero(ctx, qw, query, args...))

// Insert some permanent flags that reference no mailbox.
{
query := fmt.Sprintf("INSERT INTO %v (`%v`) VALUES ('\\Unrer2'), ('\\Unref1')",
v0.MailboxPermFlagsTableName,
v0.MailboxPermFlagsFieldValue,
)

require.NoError(t, utils.ExecQueryAndCheckUpdatedNotZero(ctx, qw, query))
}
}
// Attributes
for _, m := range testData.mailboxes {
Expand All @@ -404,6 +424,16 @@ func prepareV0Database(t *testing.T, dir, user string, testData *testData, uidGe
}

require.NoError(t, utils.ExecQueryAndCheckUpdatedNotZero(ctx, qw, query, args...))

// Insert some attributes that reference no mailbox.
{
query := fmt.Sprintf("INSERT INTO %v (`%v`) VALUES ('\\Unref2'), ('\\Unref1')",
v0.MailboxAttrsTableName,
v0.MailboxAttrsFieldValue,
)

require.NoError(t, utils.ExecQueryAndCheckUpdatedNotZero(ctx, qw, query))
}
}
}

Expand Down Expand Up @@ -453,6 +483,16 @@ func prepareV0Database(t *testing.T, dir, user string, testData *testData, uidGe
require.NoError(t, utils.ExecQueryAndCheckUpdatedNotZero(ctx, qw, query, args...))
}

// Insert some flags that reference no message.
{

query := fmt.Sprintf("INSERT INTO %v (`%v`) VALUES ('\\Seen'), ('\\Foo')",
v0.MessageFlagsTableName,
v0.MessageFlagsFieldValue,
)

require.NoError(t, utils.ExecQueryAndCheckUpdatedNotZero(ctx, qw, query))
}
}

// UIDs
Expand Down
8 changes: 7 additions & 1 deletion internal/db_impl/sqlite3/v1/mailbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,13 @@ func copyMailboxFlags(ctx context.Context,
toFieldID string,
toFieldValue string,
) error {
loadQuery := fmt.Sprintf("SELECT `%v`, `%v` FROM %v", fromFieldID, fromFieldValue, fromTableName)
loadQuery := fmt.Sprintf(
"SELECT `%v`, `%v` FROM %v WHERE `%v` IS NOT NULL",
fromFieldID,
fromFieldValue,
fromTableName,
fromFieldID,
)

flags, err := utils.MapQueryRowsFn(ctx, tx, loadQuery, scanMailboxFlag)
if err != nil {
Expand Down
9 changes: 8 additions & 1 deletion internal/db_impl/sqlite3/v1/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,18 @@ func migrateMessageFlags(ctx context.Context, tx utils.QueryWrapper) error {

// Migrate existing values to new table.
{
// Due to an issue in Ent's original generate layout it is possible to end up with flag entries that do
// not reference any message. This would cause migration failure, but we can easily skip these.
type V0MessageFlags struct {
ID imap.InternalMessageID
Value string
}
selectQuery := fmt.Sprintf("SELECT `%v`, `%v` FROM %v", v0.MessageFlagsFieldMessageID, v0.MessageFlagsFieldValue, v0.MessageFlagsTableName)
selectQuery := fmt.Sprintf("SELECT `%v`, `%v` FROM %v WHERE `%v` IS NOT NULL",
v0.MessageFlagsFieldMessageID,
v0.MessageFlagsFieldValue,
v0.MessageFlagsTableName,
v0.MessageFlagsFieldMessageID,
)

flags, err := utils.MapQueryRowsFn(ctx, tx, selectQuery, func(scanner utils.RowScanner) (V0MessageFlags, error) {
var mf V0MessageFlags
Expand Down

0 comments on commit 52391e3

Please sign in to comment.