From 0132bc78bd57638167d723e4af1de20368feea6c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 29 Jul 2026 20:40:40 +0000 Subject: [PATCH] Let WalkAll use coredata collection slice types WalkAll now accepts loaders and callbacks typed as S ~[]T so exports can use AuditLogEntries and SCIMEvents directly. Pass the trimmed page slice to walk, not the over-fetched loader result. Signed-off-by: Cursor Agent Co-authored-by: Bryan FRIMIN --- pkg/iam/log_export_csv.go | 10 ++++------ pkg/page/load_all.go | 14 +++++++++----- pkg/page/load_all_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/pkg/iam/log_export_csv.go b/pkg/iam/log_export_csv.go index 0a2846a38..564cdae7f 100644 --- a/pkg/iam/log_export_csv.go +++ b/pkg/iam/log_export_csv.go @@ -95,7 +95,7 @@ func (s *LogExportService) streamAuditLogCSV( Field: coredata.AuditLogEntryOrderFieldCreatedAt, Direction: page.OrderDirectionAsc, }, - func(ctx context.Context, cursor *page.Cursor[coredata.AuditLogEntryOrderField]) ([]*coredata.AuditLogEntry, error) { + func(ctx context.Context, cursor *page.Cursor[coredata.AuditLogEntryOrderField]) (coredata.AuditLogEntries, error) { var logs coredata.AuditLogEntries if err := logs.LoadByOrganizationID( ctx, @@ -110,8 +110,7 @@ func (s *LogExportService) streamAuditLogCSV( return logs, nil }, - func(pageEntries []*coredata.AuditLogEntry) error { - entries := coredata.AuditLogEntries(pageEntries) + func(entries coredata.AuditLogEntries) error { actorsByID, err := loadAuditLogActorExportInfo(ctx, conn, entries) if err != nil { return err @@ -154,7 +153,7 @@ func (s *LogExportService) streamSCIMEventCSV( Field: coredata.SCIMEventOrderFieldCreatedAt, Direction: page.OrderDirectionAsc, }, - func(ctx context.Context, cursor *page.Cursor[coredata.SCIMEventOrderField]) ([]*coredata.SCIMEvent, error) { + func(ctx context.Context, cursor *page.Cursor[coredata.SCIMEventOrderField]) (coredata.SCIMEvents, error) { var events coredata.SCIMEvents if err := events.LoadByOrganizationID( ctx, @@ -169,8 +168,7 @@ func (s *LogExportService) streamSCIMEventCSV( return events, nil }, - func(pageEvents []*coredata.SCIMEvent) error { - events := coredata.SCIMEvents(pageEvents) + func(events coredata.SCIMEvents) error { profilesByUserName, err := loadSCIMProfileExportInfo( ctx, conn, diff --git a/pkg/page/load_all.go b/pkg/page/load_all.go index 551d65488..946d92501 100644 --- a/pkg/page/load_all.go +++ b/pkg/page/load_all.go @@ -38,14 +38,18 @@ const MaxLoadAllPages = 20 // LoadBy* on a fresh receiver). type Loader[T Paginable[U], U OrderField] func(ctx context.Context, cursor *Cursor[U]) ([]T, error) +// WalkLoader is like Loader but allows coredata collection types (e.g. +// AuditLogEntries) whose underlying type is []T. +type WalkLoader[T Paginable[U], U OrderField, S ~[]T] func(ctx context.Context, cursor *Cursor[U]) (S, error) + // WalkAll walks every matching row via keyset pagination, advancing a // MaxCursorSize forward cursor until no rows remain, and invokes walk with // every page of rows. Unlike LoadAll, it does not apply MaxLoadAllPages. -func WalkAll[T Paginable[U], U OrderField]( +func WalkAll[T Paginable[U], U OrderField, S ~[]T]( ctx context.Context, orderBy OrderBy[U], - fetch Loader[T, U], - walk func(rows []T) error, + fetch WalkLoader[T, U, S], + walk func(rows S) error, ) error { var key *CursorKey @@ -57,8 +61,8 @@ func WalkAll[T Paginable[U], U OrderField]( return fmt.Errorf("cannot load all rows: %w", err) } - p := NewPage(rows, cursor) - if err := walk(p.Data); err != nil { + p := NewPage([]T(rows), cursor) + if err := walk(S(p.Data)); err != nil { return err } diff --git a/pkg/page/load_all_test.go b/pkg/page/load_all_test.go index 82c781e83..5ea428848 100644 --- a/pkg/page/load_all_test.go +++ b/pkg/page/load_all_test.go @@ -212,3 +212,29 @@ func TestWalkAllHasNoPageCap(t *testing.T) { assert.Equal(t, loadAllValues(store), loadAllValues(got)) assert.Greater(t, fetchs, MaxLoadAllPages) } + +type loadAllItems []*loadAllItem + +func TestWalkAllNamedSliceType(t *testing.T) { + t.Parallel() + + store := newLoadAllStore(MaxCursorSize + 1) + + var got loadAllItems + + err := WalkAll( + context.Background(), + ascOrderBy(), + func(_ context.Context, cursor *Cursor[testOrderField]) (loadAllItems, error) { + return loadAllItems(keysetPage(store, cursor)), nil + }, + func(rows loadAllItems) error { + got = append(got, rows...) + return nil + }, + ) + + require.NoError(t, err) + require.Len(t, got, len(store)) + assert.Equal(t, loadAllValues(store), loadAllValues(got)) +}