diff --git a/satellite/console/dbcleanup/chore.go b/satellite/console/dbcleanup/chore.go index 338dd7f51..70dcc6d48 100644 --- a/satellite/console/dbcleanup/chore.go +++ b/satellite/console/dbcleanup/chore.go @@ -24,8 +24,7 @@ type Config struct { AsOfSystemTimeInterval time.Duration `help:"interval for 'AS OF SYSTEM TIME' clause (CockroachDB specific) to read from the DB at a specific time in the past" default:"-5m" testDefault:"0"` PageSize int `help:"maximum number of database records to scan at once" default:"1000"` - MaxUnverifiedUserAge time.Duration `help:"maximum lifetime of unverified user account records" default:"168h"` - MaxProjectInvitationAge time.Duration `help:"maximum lifetime of project member invitation records" default:"168h"` + MaxUnverifiedUserAge time.Duration `help:"maximum lifetime of unverified user account records" default:"168h"` } // Chore periodically removes unwanted records from the satellite console database. @@ -55,13 +54,6 @@ func (chore *Chore) Run(ctx context.Context) (err error) { if err != nil { chore.log.Error("Error deleting unverified users", zap.Error(err)) } - - before = time.Now().Add(-chore.config.MaxProjectInvitationAge) - err = chore.db.ProjectInvitations().DeleteBefore(ctx, before, chore.config.AsOfSystemTimeInterval, chore.config.PageSize) - if err != nil { - chore.log.Error("Error deleting project member invitations", zap.Error(err)) - } - return nil }) } diff --git a/satellite/console/projectinvitations.go b/satellite/console/projectinvitations.go index 12c0a01b2..a809dc66e 100644 --- a/satellite/console/projectinvitations.go +++ b/satellite/console/projectinvitations.go @@ -24,8 +24,6 @@ type ProjectInvitations interface { GetByEmail(ctx context.Context, email string) ([]ProjectInvitation, error) // Delete removes a project member invitation from the database. Delete(ctx context.Context, projectID uuid.UUID, email string) error - // DeleteBefore deletes project member invitations created prior to some time from the database. - DeleteBefore(ctx context.Context, before time.Time, asOfSystemTimeInterval time.Duration, pageSize int) error } // ProjectInvitation represents a pending project member invitation. diff --git a/satellite/satellitedb/consoledb.go b/satellite/satellitedb/consoledb.go index 4cf2897bc..c76b798c7 100644 --- a/satellite/satellitedb/consoledb.go +++ b/satellite/satellitedb/consoledb.go @@ -48,7 +48,7 @@ func (db *ConsoleDB) ProjectMembers() console.ProjectMembers { // ProjectInvitations is a getter for ProjectInvitations repository. func (db *ConsoleDB) ProjectInvitations() console.ProjectInvitations { - return &projectInvitations{db.db} + return &projectInvitations{db.methods} } // APIKeys is a getter for APIKeys repository. diff --git a/satellite/satellitedb/projectinvitations.go b/satellite/satellitedb/projectinvitations.go index 4bbd812be..94c49cb3b 100644 --- a/satellite/satellitedb/projectinvitations.go +++ b/satellite/satellitedb/projectinvitations.go @@ -5,9 +5,6 @@ package satellitedb import ( "context" - "database/sql" - "errors" - "time" "storj.io/common/uuid" "storj.io/storj/satellite/console" @@ -19,7 +16,7 @@ var _ console.ProjectInvitations = (*projectInvitations)(nil) // projectInvitations is an implementation of console.ProjectInvitations. type projectInvitations struct { - db *satelliteDB + db dbx.Methods } // Upsert updates a project member invitation if it exists and inserts it otherwise. @@ -98,81 +95,6 @@ func (invites *projectInvitations) Delete(ctx context.Context, projectID uuid.UU return err } -// DeleteBefore deletes project member invitations created prior to some time from the database. -func (invites *projectInvitations) DeleteBefore( - ctx context.Context, before time.Time, asOfSystemTimeInterval time.Duration, pageSize int) (err error) { - defer mon.Task()(&ctx)(&err) - - if pageSize <= 0 { - return Error.New("expected page size to be positive; got %d", pageSize) - } - - var pageCursor, pageEnd struct { - ProjectID uuid.UUID - Email string - } - aost := invites.db.impl.AsOfSystemInterval(asOfSystemTimeInterval) - for { - // Select the ID beginning this page of records - err := invites.db.QueryRowContext(ctx, ` - SELECT project_id, email FROM project_invitations - `+aost+` - WHERE (project_id, email) > ($1, $2) AND created_at < $3 - ORDER BY (project_id, email) LIMIT 1 - `, pageCursor.ProjectID, pageCursor.Email, before).Scan(&pageCursor.ProjectID, &pageCursor.Email) - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - return nil - } - return Error.Wrap(err) - } - - // Select the ID ending this page of records - err = invites.db.QueryRowContext(ctx, ` - SELECT project_id, email FROM project_invitations - `+aost+` - WHERE (project_id, email) > ($1, $2) - ORDER BY (project_id, email) LIMIT 1 OFFSET $3 - `, pageCursor.ProjectID, pageCursor.Email, pageSize).Scan(&pageEnd.ProjectID, &pageEnd.Email) - if err != nil { - if !errors.Is(err, sql.ErrNoRows) { - return Error.Wrap(err) - } - // Since this is the last page, we want to return all remaining records - _, err = invites.db.ExecContext(ctx, ` - DELETE FROM project_invitations - WHERE (project_id, email) IN ( - SELECT project_id, email FROM project_invitations - `+aost+` - WHERE (project_id, email) >= ($1, $2) - AND created_at < $3 - ORDER BY (project_id, email) - ) - `, pageCursor.ProjectID, pageCursor.Email, before) - return Error.Wrap(err) - } - - // Delete all old, unverified records in the range between the beginning and ending IDs - _, err = invites.db.ExecContext(ctx, ` - DELETE FROM project_invitations - WHERE (project_id, email) IN ( - SELECT project_id, email FROM project_invitations - `+aost+` - WHERE (project_id, email) >= ($1, $2) - AND (project_id, email) <= ($3, $4) - AND created_at < $5 - ORDER BY (project_id, email) - ) - `, pageCursor.ProjectID, pageCursor.Email, pageEnd.ProjectID, pageEnd.Email, before) - if err != nil { - return Error.Wrap(err) - } - - // Advance the cursor to the next page - pageCursor = pageEnd - } -} - // projectInvitationFromDBX converts a project member invitation from the database to a *console.ProjectInvitation. func projectInvitationFromDBX(dbxInvite *dbx.ProjectInvitation) (_ *console.ProjectInvitation, err error) { if dbxInvite == nil { diff --git a/satellite/satellitedb/projectinvitations_test.go b/satellite/satellitedb/projectinvitations_test.go index a98c8953f..ac42d4d84 100644 --- a/satellite/satellitedb/projectinvitations_test.go +++ b/satellite/satellitedb/projectinvitations_test.go @@ -162,47 +162,3 @@ func TestProjectInvitations(t *testing.T) { }) }) } - -func TestDeleteBefore(t *testing.T) { - maxAge := time.Hour - now := time.Now() - expiration := now.Add(-maxAge) - - satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) { - invitesDB := db.Console().ProjectInvitations() - - // Only positive page sizes should be allowed. - require.Error(t, invitesDB.DeleteBefore(ctx, time.Time{}, 0, 0)) - require.Error(t, invitesDB.DeleteBefore(ctx, time.Time{}, 0, -1)) - - createInvite := func() *console.ProjectInvitation { - projID := testrand.UUID() - _, err := db.Console().Projects().Insert(ctx, &console.Project{ID: projID}) - require.NoError(t, err) - - invite, err := invitesDB.Upsert(ctx, &console.ProjectInvitation{ProjectID: projID}) - require.NoError(t, err) - return invite - } - - newInvite := createInvite() - - oldInvite := createInvite() - result, err := db.Testing().RawDB().ExecContext(ctx, - "UPDATE project_invitations SET created_at = $1 WHERE project_id = $2", - expiration.Add(-time.Second), oldInvite.ProjectID, - ) - require.NoError(t, err) - count, err := result.RowsAffected() - require.NoError(t, err) - require.EqualValues(t, 1, count) - - require.NoError(t, invitesDB.DeleteBefore(ctx, expiration, 0, 1)) - - // Ensure that the old invitation record was deleted and the other remains. - _, err = invitesDB.Get(ctx, oldInvite.ProjectID, oldInvite.Email) - require.ErrorIs(t, err, sql.ErrNoRows) - _, err = invitesDB.Get(ctx, newInvite.ProjectID, newInvite.Email) - require.NoError(t, err) - }) -} diff --git a/scripts/testdata/satellite-config.yaml.lock b/scripts/testdata/satellite-config.yaml.lock index 475f6c9d1..1a947b24d 100755 --- a/scripts/testdata/satellite-config.yaml.lock +++ b/scripts/testdata/satellite-config.yaml.lock @@ -145,9 +145,6 @@ compensation.withheld-percents: 75,75,75,50,50,50,25,25,25,0,0,0,0,0,0 # interval between chore cycles # console-db-cleanup.interval: 24h0m0s -# maximum lifetime of project member invitation records -# console-db-cleanup.max-project-invitation-age: 168h0m0s - # maximum lifetime of unverified user account records # console-db-cleanup.max-unverified-user-age: 168h0m0s