setting aside

This commit is contained in:
ryanfkeepers 2023-08-28 13:52:45 -06:00
parent b0eb3109dd
commit 7f6caf5fbe
22 changed files with 335 additions and 494 deletions

View File

@ -85,7 +85,7 @@ func collectItems(
invalidPrevDelta = true invalidPrevDelta = true
newPaths = map[string]string{} newPaths = map[string]string{}
pager.Reset(ctx) pager.Reset()
continue continue
} }
@ -94,16 +94,11 @@ func collectItems(
return DeltaUpdate{}, nil, nil, graph.Wrap(ctx, err, "getting page") return DeltaUpdate{}, nil, nil, graph.Wrap(ctx, err, "getting page")
} }
vals, err := pager.ValuesIn(page)
if err != nil {
return DeltaUpdate{}, nil, nil, graph.Wrap(ctx, err, "extracting items from response")
}
err = collector( err = collector(
ctx, ctx,
driveID, driveID,
driveName, driveName,
vals, page.GetValue(),
oldPaths, oldPaths,
newPaths, newPaths,
excluded, excluded,

View File

@ -182,7 +182,7 @@ func (uc *urlCache) deltaQuery(
) error { ) error {
logger.Ctx(ctx).Debug("starting delta query") logger.Ctx(ctx).Debug("starting delta query")
// Reset item pager to remove any previous state // Reset item pager to remove any previous state
uc.itemPager.Reset(ctx) uc.itemPager.Reset()
_, _, _, err := collectItems( _, _, _, err := collectItems(
ctx, ctx,

View File

@ -243,7 +243,7 @@ func populateCollections(
func collectItems( func collectItems(
ctx context.Context, ctx context.Context,
pager api.ChannelMessageDeltaEnumerator, pager api.DeltaPager[models.ChatMessageable],
) ([]models.ChatMessageable, error) { ) ([]models.ChatMessageable, error) {
items := []models.ChatMessageable{} items := []models.ChatMessageable{}
@ -265,11 +265,7 @@ func collectItems(
// continue // continue
// } // }
vals, err := pager.ValuesIn(page) vals := page.GetValue()
if err != nil {
return nil, graph.Wrap(ctx, err, "getting items in page")
}
items = append(items, vals...) items = append(items, vals...)
nextLink, _ := api.NextAndDeltaLink(page) nextLink, _ := api.NextAndDeltaLink(page)

View File

@ -16,7 +16,7 @@ type BackupHandler interface {
) (models.Channelable, error) ) (models.Channelable, error)
NewChannelsPager( NewChannelsPager(
teamID string, teamID string,
) api.ChannelDeltaEnumerator ) api.DeltaPager[models.Channelable]
GetMessageByID( GetMessageByID(
ctx context.Context, ctx context.Context,
@ -24,7 +24,7 @@ type BackupHandler interface {
) (models.ChatMessageable, error) ) (models.ChatMessageable, error)
NewMessagePager( NewMessagePager(
teamID, channelID string, teamID, channelID string,
) api.ChannelMessageDeltaEnumerator ) api.DeltaPager[models.ChatMessageable]
GetMessageReplies( GetMessageReplies(
ctx context.Context, ctx context.Context,
@ -34,7 +34,7 @@ type BackupHandler interface {
type BackupMessagesHandler interface { type BackupMessagesHandler interface {
GetMessage(ctx context.Context, teamID, channelID, itemID string) (models.ChatMessageable, error) GetMessage(ctx context.Context, teamID, channelID, itemID string) (models.ChatMessageable, error)
NewMessagePager(teamID, channelID string) api.ChannelMessageDeltaEnumerator NewMessagePager(teamID, channelID string) api.DeltaPager[models.ChatMessageable]
GetChannel(ctx context.Context, teamID, channelID string) (models.Channelable, error) GetChannel(ctx context.Context, teamID, channelID string) (models.Channelable, error)
GetReply(ctx context.Context, teamID, channelID, messageID string) (serialization.Parsable, error) GetReply(ctx context.Context, teamID, channelID, messageID string) (serialization.Parsable, error)
} }

View File

@ -90,7 +90,7 @@ func (c Contacts) EnumerateContainers(
// item pager // item pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemPager[models.Contactable] = &contactsPageCtrl{} var _ Pager[models.Contactable] = &contactsPageCtrl{}
type contactsPageCtrl struct { type contactsPageCtrl struct {
gs graph.Servicer gs graph.Servicer
@ -100,10 +100,11 @@ type contactsPageCtrl struct {
func (c Contacts) NewContactsPager( func (c Contacts) NewContactsPager(
userID, containerID string, userID, containerID string,
immutableIDs bool,
selectProps ...string, selectProps ...string,
) itemPager[models.Contactable] { ) Pager[models.Contactable] {
options := &users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration{ options := &users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize)), Headers: newPreferHeaders(preferPageSize(c.options.DeltaPageSize), preferImmutableIDs(immutableIDs)),
QueryParameters: &users.ItemContactFoldersItemContactsRequestBuilderGetQueryParameters{}, QueryParameters: &users.ItemContactFoldersItemContactsRequestBuilderGetQueryParameters{},
// do NOT set Top. It limits the total items received. // do NOT set Top. It limits the total items received.
} }
@ -129,22 +130,98 @@ func (c Contacts) NewContactsPager(
return &contactsPageCtrl{c.Stable, builder, options} return &contactsPageCtrl{c.Stable, builder, options}
} }
//lint:ignore U1000 False Positive func (p *contactsPageCtrl) GetPage(ctx context.Context) (LinkValuer[models.Contactable], error) {
func (p *contactsPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.Contactable], error) {
resp, err := p.builder.Get(ctx, p.options) resp, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
} }
return EmptyDeltaLinker[models.Contactable]{PageLinkValuer: resp}, nil return EmptyDeltaLinker[models.Contactable]{LinkValuer: resp}, nil
} }
//lint:ignore U1000 False Positive func (p *contactsPageCtrl) SetNext(nextLink string) {
func (p *contactsPageCtrl) setNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemContactFoldersItemContactsRequestBuilder(nextLink, p.gs.Adapter())
} }
//lint:ignore U1000 False Positive // ---------------------------------------------------------------------------
// delta pager
// ---------------------------------------------------------------------------
var _ DeltaPager[models.Contactable] = &contactDeltaPager{}
type contactDeltaPager struct {
gs graph.Servicer
userID string
containerID string
builder *users.ItemContactFoldersItemContactsDeltaRequestBuilder
options *users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration
}
func getContactDeltaBuilder(
ctx context.Context,
gs graph.Servicer,
userID, containerID string,
options *users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration,
) *users.ItemContactFoldersItemContactsDeltaRequestBuilder {
builder := gs.Client().
Users().
ByUserId(userID).
ContactFolders().
ByContactFolderId(containerID).
Contacts().
Delta()
return builder
}
func (c Contacts) NewContactsDeltaPager(
ctx context.Context,
userID, containerID, oldDelta string,
immutableIDs bool,
selectProps ...string,
) DeltaPager[getIDAndAddtler] {
options := &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(c.options.DeltaPageSize), preferImmutableIDs(immutableIDs)),
QueryParameters: &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetQueryParameters{
// do NOT set Top. It limits the total items received.
},
}
if len(selectProps) > 0 {
options.QueryParameters.Select = selectProps
}
var builder *users.ItemContactFoldersItemContactsDeltaRequestBuilder
if oldDelta != "" {
builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(oldDelta, c.Stable.Adapter())
} else {
builder = getContactDeltaBuilder(ctx, c.Stable, userID, containerID, options)
}
return &contactDeltaPager{c.Stable, userID, containerID, builder, options}
}
func (p *contactDeltaPager) GetPage(ctx context.Context) (DeltaLinkValuer[models.Contactable], error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
}
func (p *contactDeltaPager) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(nextLink, p.gs.Adapter())
}
func (p *contactDeltaPager) Reset(ctx context.Context) {
p.builder = getContactDeltaBuilder(ctx, p.gs, p.userID, p.containerID, p.options)
}
// ---------------------------------------------------------------------------
// runners
// ---------------------------------------------------------------------------
func (c Contacts) GetItemsInContainerByCollisionKey( func (c Contacts) GetItemsInContainerByCollisionKey(
ctx context.Context, ctx context.Context,
userID, containerID string, userID, containerID string,
@ -171,7 +248,7 @@ func (c Contacts) GetItemIDsInContainer(
userID, containerID string, userID, containerID string,
) (map[string]struct{}, error) { ) (map[string]struct{}, error) {
ctx = clues.Add(ctx, "container_id", containerID) ctx = clues.Add(ctx, "container_id", containerID)
pager := c.NewContactsPager(userID, containerID, "id") pager := c.NewContactsPager(userID, containerID, false, "id")
items, err := enumerateItems(ctx, pager) items, err := enumerateItems(ctx, pager)
if err != nil { if err != nil {
@ -187,130 +264,6 @@ func (c Contacts) GetItemIDsInContainer(
return m, nil return m, nil
} }
// ---------------------------------------------------------------------------
// item ID pager
// ---------------------------------------------------------------------------
var _ DeltaPager[getIDAndAddtler] = &contactIDPager{}
type contactIDPager struct {
gs graph.Servicer
builder *users.ItemContactFoldersItemContactsRequestBuilder
options *users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration
}
func (c Contacts) NewContactIDsPager(
ctx context.Context,
userID, containerID string,
immutableIDs bool,
) DeltaPager[getIDAndAddtler] {
config := &users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersItemContactsRequestBuilderGetQueryParameters{
Select: idAnd(parentFolderID),
// do NOT set Top. It limits the total items received.
},
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize), preferImmutableIDs(immutableIDs)),
}
builder := c.Stable.
Client().
Users().
ByUserId(userID).
ContactFolders().
ByContactFolderId(containerID).
Contacts()
return &contactIDPager{c.Stable, builder, config}
}
func (p *contactIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.Contactable]{PageLinkValuer: resp}, nil
}
func (p *contactIDPager) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsRequestBuilder(nextLink, p.gs.Adapter())
}
// non delta pagers don't need reset
func (p *contactIDPager) Reset(context.Context) {}
func (p *contactIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Contactable](pl)
}
// ---------------------------------------------------------------------------
// delta item ID pager
// ---------------------------------------------------------------------------
var _ DeltaPager[getIDAndAddtler] = &contactDeltaIDPager{}
type contactDeltaIDPager struct {
gs graph.Servicer
userID string
containerID string
builder *users.ItemContactFoldersItemContactsDeltaRequestBuilder
options *users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration
}
func getContactDeltaBuilder(
ctx context.Context,
gs graph.Servicer,
userID, containerID string,
options *users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration,
) *users.ItemContactFoldersItemContactsDeltaRequestBuilder {
builder := gs.Client().Users().ByUserId(userID).ContactFolders().ByContactFolderId(containerID).Contacts().Delta()
return builder
}
func (c Contacts) NewContactDeltaIDsPager(
ctx context.Context,
userID, containerID, oldDelta string,
immutableIDs bool,
) DeltaPager[getIDAndAddtler] {
options := &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetQueryParameters{
Select: idAnd(parentFolderID),
// do NOT set Top. It limits the total items received.
},
Headers: newPreferHeaders(preferPageSize(c.options.DeltaPageSize), preferImmutableIDs(immutableIDs)),
}
var builder *users.ItemContactFoldersItemContactsDeltaRequestBuilder
if oldDelta != "" {
builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(oldDelta, c.Stable.Adapter())
} else {
builder = getContactDeltaBuilder(ctx, c.Stable, userID, containerID, options)
}
return &contactDeltaIDPager{c.Stable, userID, containerID, builder, options}
}
func (p *contactDeltaIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
}
func (p *contactDeltaIDPager) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(nextLink, p.gs.Adapter())
}
func (p *contactDeltaIDPager) Reset(ctx context.Context) {
p.builder = getContactDeltaBuilder(ctx, p.gs, p.userID, p.containerID, p.options)
}
func (p *contactDeltaIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Contactable](pl)
}
func (c Contacts) GetAddedAndRemovedItemIDs( func (c Contacts) GetAddedAndRemovedItemIDs(
ctx context.Context, ctx context.Context,
userID, containerID, oldDelta string, userID, containerID, oldDelta string,
@ -322,8 +275,14 @@ func (c Contacts) GetAddedAndRemovedItemIDs(
"category", selectors.ExchangeContact, "category", selectors.ExchangeContact,
"container_id", containerID) "container_id", containerID)
pager := c.NewContactIDsPager(ctx, userID, containerID, immutableIDs) pager := c.NewContactsPager(userID, containerID, immutableIDs, idAnd(parentFolderID)...)
deltaPager := c.NewContactDeltaIDsPager(ctx, userID, containerID, oldDelta, immutableIDs) deltaPager := c.NewContactsDeltaPager(ctx, userID, containerID, oldDelta, immutableIDs, idAnd(parentFolderID)...)
return getAddedAndRemovedItemIDs(ctx, c.Stable, pager, deltaPager, oldDelta, canMakeDeltaQueries) return getAddedAndRemovedItemIDs[models.Contactable](
ctx,
c.Stable,
pager,
deltaPager,
oldDelta,
canMakeDeltaQueries)
} }

View File

@ -39,13 +39,13 @@ func (suite *ContactsPagerIntgSuite) TestContacts_GetItemsInContainerByCollision
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
container, err := ac.GetContainerByID(ctx, suite.its.userID, "contacts") container, err := ac.GetContainerByID(ctx, suite.its.user.id, "contacts")
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
conts, err := ac.Stable. conts, err := ac.Stable.
Client(). Client().
Users(). Users().
ByUserId(suite.its.userID). ByUserId(suite.its.user.id).
ContactFolders(). ContactFolders().
ByContactFolderId(ptr.Val(container.GetId())). ByContactFolderId(ptr.Val(container.GetId())).
Contacts(). Contacts().
@ -61,7 +61,7 @@ func (suite *ContactsPagerIntgSuite) TestContacts_GetItemsInContainerByCollision
expect := maps.Keys(expectM) expect := maps.Keys(expectM)
results, err := suite.its.ac.Contacts().GetItemsInContainerByCollisionKey(ctx, suite.its.userID, "contacts") results, err := suite.its.ac.Contacts().GetItemsInContainerByCollisionKey(ctx, suite.its.user.id, "contacts")
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result") require.Less(t, 0, len(results), "requires at least one result")
@ -91,13 +91,13 @@ func (suite *ContactsPagerIntgSuite) TestContacts_GetItemsIDsInContainer() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
container, err := ac.GetContainerByID(ctx, suite.its.userID, api.DefaultContacts) container, err := ac.GetContainerByID(ctx, suite.its.user.id, api.DefaultContacts)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
msgs, err := ac.Stable. msgs, err := ac.Stable.
Client(). Client().
Users(). Users().
ByUserId(suite.its.userID). ByUserId(suite.its.user.id).
ContactFolders(). ContactFolders().
ByContactFolderId(ptr.Val(container.GetId())). ByContactFolderId(ptr.Val(container.GetId())).
Contacts(). Contacts().
@ -112,7 +112,7 @@ func (suite *ContactsPagerIntgSuite) TestContacts_GetItemsIDsInContainer() {
} }
results, err := suite.its.ac.Contacts(). results, err := suite.its.ac.Contacts().
GetItemIDsInContainer(ctx, suite.its.userID, api.DefaultContacts) GetItemIDsInContainer(ctx, suite.its.user.id, api.DefaultContacts)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result") require.Less(t, 0, len(results), "requires at least one result")
require.Equal(t, len(expect), len(results), "must have same count of items") require.Equal(t, len(expect), len(results), "must have same count of items")

View File

@ -141,7 +141,7 @@ func (suite *ContactsAPIIntgSuite) TestContacts_GetContainerByName() {
cc, err := suite.its.ac.Contacts().CreateContainer( cc, err := suite.its.ac.Contacts().CreateContainer(
ctx, ctx,
suite.its.userID, suite.its.user.id,
"", "",
rc.Location) rc.Location)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -168,7 +168,7 @@ func (suite *ContactsAPIIntgSuite) TestContacts_GetContainerByName() {
_, err := suite.its.ac. _, err := suite.its.ac.
Contacts(). Contacts().
GetContainerByName(ctx, suite.its.userID, "", test.name) GetContainerByName(ctx, suite.its.user.id, "", test.name)
test.expectErr(t, err, clues.ToCore(err)) test.expectErr(t, err, clues.ToCore(err))
}) })
} }

View File

@ -2,7 +2,6 @@ package api
import ( import (
"context" "context"
"fmt"
"time" "time"
"github.com/alcionai/clues" "github.com/alcionai/clues"
@ -21,7 +20,7 @@ import (
// non-delta item pager // non-delta item pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemPager[models.DriveItemable] = &driveItemPageCtrl{} var _ Pager[models.DriveItemable] = &driveItemPageCtrl{}
type driveItemPageCtrl struct { type driveItemPageCtrl struct {
gs graph.Servicer gs graph.Servicer
@ -32,7 +31,7 @@ type driveItemPageCtrl struct {
func (c Drives) NewDriveItemPager( func (c Drives) NewDriveItemPager(
driveID, containerID string, driveID, containerID string,
selectProps ...string, selectProps ...string,
) itemPager[models.DriveItemable] { ) Pager[models.DriveItemable] {
options := &drives.ItemItemsItemChildrenRequestBuilderGetRequestConfiguration{ options := &drives.ItemItemsItemChildrenRequestBuilderGetRequestConfiguration{
QueryParameters: &drives.ItemItemsItemChildrenRequestBuilderGetQueryParameters{}, QueryParameters: &drives.ItemItemsItemChildrenRequestBuilderGetQueryParameters{},
} }
@ -53,17 +52,16 @@ func (c Drives) NewDriveItemPager(
} }
//lint:ignore U1000 False Positive //lint:ignore U1000 False Positive
func (p *driveItemPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.DriveItemable], error) { func (p *driveItemPageCtrl) GetPage(ctx context.Context) (LinkValuer[models.DriveItemable], error) {
page, err := p.builder.Get(ctx, p.options) page, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
} }
return EmptyDeltaLinker[models.DriveItemable]{PageLinkValuer: page}, nil return EmptyDeltaLinker[models.DriveItemable]{LinkValuer: page}, nil
} }
//lint:ignore U1000 False Positive func (p *driveItemPageCtrl) SetNext(nextLink string) {
func (p *driveItemPageCtrl) setNext(nextLink string) {
p.builder = drives.NewItemItemsItemChildrenRequestBuilder(nextLink, p.gs.Adapter()) p.builder = drives.NewItemItemsItemChildrenRequestBuilder(nextLink, p.gs.Adapter())
} }
@ -105,7 +103,7 @@ func (c Drives) GetItemIDsInContainer(
items, err := enumerateItems(ctx, pager) items, err := enumerateItems(ctx, pager)
if err != nil { if err != nil {
return nil, graph.Wrap(ctx, err, "enumerating contacts") return nil, graph.Wrap(ctx, err, "enumerating drive items")
} }
m := map[string]DriveItemIDType{} m := map[string]DriveItemIDType{}
@ -171,25 +169,16 @@ func (c Drives) NewDriveItemDeltaPager(
return res return res
} }
func (p *DriveItemDeltaPageCtrl) GetPage(ctx context.Context) (DeltaPageLinker, error) { func (p *DriveItemDeltaPageCtrl) GetPage(ctx context.Context) (DeltaLinkValuer[models.DriveItemable], error) {
var ( resp, err := p.builder.Get(ctx, p.options)
resp DeltaPageLinker return resp, graph.Stack(ctx, err).OrNil()
err error
)
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
} }
func (p *DriveItemDeltaPageCtrl) SetNext(link string) { func (p *DriveItemDeltaPageCtrl) SetNext(link string) {
p.builder = drives.NewItemItemsItemDeltaRequestBuilder(link, p.gs.Adapter()) p.builder = drives.NewItemItemsItemDeltaRequestBuilder(link, p.gs.Adapter())
} }
func (p *DriveItemDeltaPageCtrl) Reset(context.Context) { func (p *DriveItemDeltaPageCtrl) Reset() {
p.builder = p.gs.Client(). p.builder = p.gs.Client().
Drives(). Drives().
ByDriveId(p.driveID). ByDriveId(p.driveID).
@ -198,10 +187,6 @@ func (p *DriveItemDeltaPageCtrl) Reset(context.Context) {
Delta() Delta()
} }
func (p *DriveItemDeltaPageCtrl) ValuesIn(l PageLinker) ([]models.DriveItemable, error) {
return getValues[models.DriveItemable](l)
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// user's drives pager // user's drives pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -245,12 +230,11 @@ type nopUserDrivePageLinker struct {
func (nl nopUserDrivePageLinker) GetOdataNextLink() *string { return nil } func (nl nopUserDrivePageLinker) GetOdataNextLink() *string { return nil }
func (p *userDrivePager) GetPage(ctx context.Context) (PageLinker, error) { func (nl nopUserDrivePageLinker) GetValue() []models.Driveable {
var ( return []models.Driveable{nl.drive}
resp PageLinker }
err error
)
func (p *userDrivePager) GetPage(ctx context.Context) (LinkValuer[models.Driveable], error) {
d, err := p.gs. d, err := p.gs.
Client(). Client().
Users(). Users().
@ -261,7 +245,7 @@ func (p *userDrivePager) GetPage(ctx context.Context) (PageLinker, error) {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
} }
resp = &nopUserDrivePageLinker{drive: d} var resp LinkValuer[models.Driveable] = &nopUserDrivePageLinker{drive: d}
// TODO(keepers): turn back on when we can separate drive enumeration // TODO(keepers): turn back on when we can separate drive enumeration
// from default drive lookup. // from default drive lookup.
@ -278,20 +262,6 @@ func (p *userDrivePager) SetNext(link string) {
p.builder = users.NewItemDrivesRequestBuilder(link, p.gs.Adapter()) p.builder = users.NewItemDrivesRequestBuilder(link, p.gs.Adapter())
} }
func (p *userDrivePager) ValuesIn(l PageLinker) ([]models.Driveable, error) {
nl, ok := l.(*nopUserDrivePageLinker)
if !ok || nl == nil {
return nil, clues.New(fmt.Sprintf("improper page linker struct for user drives: %T", l))
}
// TODO(keepers): turn back on when we can separate drive enumeration
// from default drive lookup.
// return getValues[models.Driveable](l)
return []models.Driveable{nl.drive}, nil
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// site's libraries pager // site's libraries pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -332,28 +302,15 @@ func (c Drives) NewSiteDrivePager(
return res return res
} }
func (p *siteDrivePager) GetPage(ctx context.Context) (PageLinker, error) { func (p *siteDrivePager) GetPage(ctx context.Context) (LinkValuer[models.Driveable], error) {
var ( resp, err := p.builder.Get(ctx, p.options)
resp PageLinker return resp, graph.Stack(ctx, err).OrNil()
err error
)
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
} }
func (p *siteDrivePager) SetNext(link string) { func (p *siteDrivePager) SetNext(link string) {
p.builder = sites.NewItemDrivesRequestBuilder(link, p.gs.Adapter()) p.builder = sites.NewItemDrivesRequestBuilder(link, p.gs.Adapter())
} }
func (p *siteDrivePager) ValuesIn(l PageLinker) ([]models.Driveable, error) {
return getValues[models.Driveable](l)
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// drive pager // drive pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -374,8 +331,8 @@ func GetAllDrives(
// Loop through all pages returned by Graph API. // Loop through all pages returned by Graph API.
for { for {
var ( var (
page LinkValuer[models.Driveable]
err error err error
page PageLinker
) )
// Retry Loop for Drive retrieval. Request can timeout // Retry Loop for Drive retrieval. Request can timeout
@ -400,12 +357,8 @@ func GetAllDrives(
break break
} }
tmp, err := pager.ValuesIn(page) items := page.GetValue()
if err != nil { ds = append(ds, items...)
return nil, graph.Wrap(ctx, err, "extracting drives from response")
}
ds = append(ds, tmp...)
nextLink := ptr.Val(page.GetOdataNextLink()) nextLink := ptr.Val(page.GetOdataNextLink())
if len(nextLink) == 0 { if len(nextLink) == 0 {
@ -419,17 +372,3 @@ func GetAllDrives(
return ds, nil return ds, nil
} }
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
func getValues[T any](l PageLinker) ([]T, error) {
page, ok := l.(interface{ GetValue() []T })
if !ok {
return nil, clues.New("page does not comply with GetValue() interface").
With("page_item_type", fmt.Sprintf("%T", l))
}
return page.GetValue(), nil
}

View File

@ -39,13 +39,13 @@ func (suite *DrivePagerIntgSuite) TestDrives_GetItemsInContainerByCollisionKey()
}{ }{
{ {
name: "user drive", name: "user drive",
driveID: suite.its.userDriveID, driveID: suite.its.user.driveID,
rootFolderID: suite.its.userDriveRootFolderID, rootFolderID: suite.its.user.driveRootFolderID,
}, },
{ {
name: "site drive", name: "site drive",
driveID: suite.its.siteDriveID, driveID: suite.its.site.driveID,
rootFolderID: suite.its.siteDriveRootFolderID, rootFolderID: suite.its.site.driveRootFolderID,
}, },
} }
for _, test := range table { for _, test := range table {
@ -75,7 +75,7 @@ func (suite *DrivePagerIntgSuite) TestDrives_GetItemsInContainerByCollisionKey()
t, t,
ims, ims,
"need at least one item to compare in user %s drive %s folder %s", "need at least one item to compare in user %s drive %s folder %s",
suite.its.userID, test.driveID, test.rootFolderID) suite.its.user.id, test.driveID, test.rootFolderID)
results, err := suite.its.ac. results, err := suite.its.ac.
Drives(). Drives().
@ -113,13 +113,13 @@ func (suite *DrivePagerIntgSuite) TestDrives_GetItemIDsInContainer() {
}{ }{
{ {
name: "user drive", name: "user drive",
driveID: suite.its.userDriveID, driveID: suite.its.user.driveID,
rootFolderID: suite.its.userDriveRootFolderID, rootFolderID: suite.its.user.driveRootFolderID,
}, },
{ {
name: "site drive", name: "site drive",
driveID: suite.its.siteDriveID, driveID: suite.its.site.driveID,
rootFolderID: suite.its.siteDriveRootFolderID, rootFolderID: suite.its.site.driveRootFolderID,
}, },
} }
for _, test := range table { for _, test := range table {
@ -149,7 +149,7 @@ func (suite *DrivePagerIntgSuite) TestDrives_GetItemIDsInContainer() {
t, t,
igv, igv,
"need at least one item to compare in user %s drive %s folder %s", "need at least one item to compare in user %s drive %s folder %s",
suite.its.userID, test.driveID, test.rootFolderID) suite.its.user.id, test.driveID, test.rootFolderID)
for _, itm := range igv { for _, itm := range igv {
expect[ptr.Val(itm.GetId())] = api.DriveItemIDType{ expect[ptr.Val(itm.GetId())] = api.DriveItemIDType{

View File

@ -76,8 +76,8 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer() {
// generate a parent for the test data // generate a parent for the test data
parent, err := acd.PostItemInContainer( parent, err := acd.PostItemInContainer(
ctx, ctx,
suite.its.userDriveID, suite.its.user.driveID,
suite.its.userDriveRootFolderID, suite.its.user.driveRootFolderID,
newItem(rc.Location, true), newItem(rc.Location, true),
control.Replace) control.Replace)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -86,7 +86,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer() {
folder := newItem("collision", true) folder := newItem("collision", true)
origFolder, err := acd.PostItemInContainer( origFolder, err := acd.PostItemInContainer(
ctx, ctx,
suite.its.userDriveID, suite.its.user.driveID,
ptr.Val(parent.GetId()), ptr.Val(parent.GetId()),
folder, folder,
control.Copy) control.Copy)
@ -96,7 +96,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer() {
file := newItem("collision.txt", false) file := newItem("collision.txt", false)
origFile, err := acd.PostItemInContainer( origFile, err := acd.PostItemInContainer(
ctx, ctx,
suite.its.userDriveID, suite.its.user.driveID,
ptr.Val(parent.GetId()), ptr.Val(parent.GetId()),
file, file,
control.Copy) control.Copy)
@ -211,7 +211,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer() {
t := suite.T() t := suite.T()
i, err := acd.PostItemInContainer( i, err := acd.PostItemInContainer(
ctx, ctx,
suite.its.userDriveID, suite.its.user.driveID,
ptr.Val(parent.GetId()), ptr.Val(parent.GetId()),
test.postItem, test.postItem,
test.onCollision) test.onCollision)
@ -239,8 +239,8 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer_replaceFolderRegr
// generate a folder for the test data // generate a folder for the test data
folder, err := acd.PostItemInContainer( folder, err := acd.PostItemInContainer(
ctx, ctx,
suite.its.userDriveID, suite.its.user.driveID,
suite.its.userDriveRootFolderID, suite.its.user.driveRootFolderID,
newItem(rc.Location, true), newItem(rc.Location, true),
// skip instead of replace here to get // skip instead of replace here to get
// an ErrItemAlreadyExistsConflict, just in case. // an ErrItemAlreadyExistsConflict, just in case.
@ -252,7 +252,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer_replaceFolderRegr
file := newItem(fmt.Sprintf("collision_%d.txt", i), false) file := newItem(fmt.Sprintf("collision_%d.txt", i), false)
f, err := acd.PostItemInContainer( f, err := acd.PostItemInContainer(
ctx, ctx,
suite.its.userDriveID, suite.its.user.driveID,
ptr.Val(folder.GetId()), ptr.Val(folder.GetId()),
file, file,
control.Copy) control.Copy)
@ -263,7 +263,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer_replaceFolderRegr
resultFolder, err := acd.PostItemInContainer( resultFolder, err := acd.PostItemInContainer(
ctx, ctx,
suite.its.userDriveID, suite.its.user.driveID,
ptr.Val(folder.GetParentReference().GetId()), ptr.Val(folder.GetParentReference().GetId()),
newItem(rc.Location, true), newItem(rc.Location, true),
control.Replace) control.Replace)
@ -274,7 +274,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer_replaceFolderRegr
resultFileColl, err := acd.Stable. resultFileColl, err := acd.Stable.
Client(). Client().
Drives(). Drives().
ByDriveId(suite.its.userDriveID). ByDriveId(suite.its.user.driveID).
Items(). Items().
ByDriveItemId(ptr.Val(resultFolder.GetId())). ByDriveItemId(ptr.Val(resultFolder.GetId())).
Children(). Children().

View File

@ -98,7 +98,7 @@ func (c Events) EnumerateContainers(
// item pager // item pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemPager[models.Eventable] = &eventsPageCtrl{} var _ Pager[models.Eventable] = &eventsPageCtrl{}
type eventsPageCtrl struct { type eventsPageCtrl struct {
gs graph.Servicer gs graph.Servicer
@ -109,7 +109,7 @@ type eventsPageCtrl struct {
func (c Events) NewEventsPager( func (c Events) NewEventsPager(
userID, containerID string, userID, containerID string,
selectProps ...string, selectProps ...string,
) itemPager[models.Eventable] { ) Pager[models.Eventable] {
options := &users.ItemCalendarsItemEventsRequestBuilderGetRequestConfiguration{ options := &users.ItemCalendarsItemEventsRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize)), Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize)),
QueryParameters: &users.ItemCalendarsItemEventsRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemCalendarsItemEventsRequestBuilderGetQueryParameters{
@ -133,13 +133,11 @@ func (c Events) NewEventsPager(
} }
//lint:ignore U1000 False Positive //lint:ignore U1000 False Positive
func (p *eventsPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.Eventable], error) { func (p *eventsPageCtrl) getPage(
ctx context.Context,
) (LinkValuer[models.Eventable], error) {
resp, err := p.builder.Get(ctx, p.options) resp, err := p.builder.Get(ctx, p.options)
if err != nil { return resp, graph.Stack(ctx, err).OrNil()
return nil, graph.Stack(ctx, err)
}
return resp, nil
} }
//lint:ignore U1000 False Positive //lint:ignore U1000 False Positive
@ -204,13 +202,11 @@ func (c Events) NewEventIDsPager(
return &eventIDPager{c.Stable, builder, options}, nil return &eventIDPager{c.Stable, builder, options}, nil
} }
func (p *eventIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) { func (p *eventIDPager) GetPage(
ctx context.Context,
) (LinkValuer[models.Eventable], error) {
resp, err := p.builder.Get(ctx, p.options) resp, err := p.builder.Get(ctx, p.options)
if err != nil { return EmptyDeltaLinker[models.Eventable]{LinkValuer: resp}, graph.Stack(ctx, err).OrNil()
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.Eventable]{PageLinkValuer: resp}, nil
} }
func (p *eventIDPager) SetNext(nextLink string) { func (p *eventIDPager) SetNext(nextLink string) {
@ -218,11 +214,7 @@ func (p *eventIDPager) SetNext(nextLink string) {
} }
// non delta pagers don't need reset // non delta pagers don't need reset
func (p *eventIDPager) Reset(context.Context) {} func (p *eventIDPager) Reset() {}
func (p *eventIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Eventable](pl)
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// delta item ID pager // delta item ID pager
@ -253,7 +245,7 @@ func (c Events) NewEventDeltaIDsPager(
var builder *users.ItemCalendarsItemEventsDeltaRequestBuilder var builder *users.ItemCalendarsItemEventsDeltaRequestBuilder
if oldDelta == "" { if oldDelta == "" {
builder = getEventDeltaBuilder(ctx, c.Stable, userID, containerID, options) builder = getEventDeltaBuilder(c.Stable, userID, containerID, options)
} else { } else {
builder = users.NewItemCalendarsItemEventsDeltaRequestBuilder(oldDelta, c.Stable.Adapter()) builder = users.NewItemCalendarsItemEventsDeltaRequestBuilder(oldDelta, c.Stable.Adapter())
} }
@ -262,7 +254,6 @@ func (c Events) NewEventDeltaIDsPager(
} }
func getEventDeltaBuilder( func getEventDeltaBuilder(
ctx context.Context,
gs graph.Servicer, gs graph.Servicer,
userID, containerID string, userID, containerID string,
options *users.ItemCalendarsItemEventsDeltaRequestBuilderGetRequestConfiguration, options *users.ItemCalendarsItemEventsDeltaRequestBuilderGetRequestConfiguration,
@ -281,25 +272,19 @@ func getEventDeltaBuilder(
return builder return builder
} }
func (p *eventDeltaIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) { func (p *eventDeltaIDPager) GetPage(
ctx context.Context,
) (DeltaLinkValuer[models.Eventable], error) {
resp, err := p.builder.Get(ctx, p.options) resp, err := p.builder.Get(ctx, p.options)
if err != nil { return resp, graph.Stack(ctx, err).OrNil()
return nil, graph.Stack(ctx, err)
}
return resp, nil
} }
func (p *eventDeltaIDPager) SetNext(nextLink string) { func (p *eventDeltaIDPager) SetNext(nextLink string) {
p.builder = users.NewItemCalendarsItemEventsDeltaRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemCalendarsItemEventsDeltaRequestBuilder(nextLink, p.gs.Adapter())
} }
func (p *eventDeltaIDPager) Reset(ctx context.Context) { func (p *eventDeltaIDPager) Reset() {
p.builder = getEventDeltaBuilder(ctx, p.gs, p.userID, p.containerID, p.options) p.builder = getEventDeltaBuilder(p.gs, p.userID, p.containerID, p.options)
}
func (p *eventDeltaIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Eventable](pl)
} }
func (c Events) GetAddedAndRemovedItemIDs( func (c Events) GetAddedAndRemovedItemIDs(

View File

@ -39,13 +39,13 @@ func (suite *EventsPagerIntgSuite) TestEvents_GetItemsInContainerByCollisionKey(
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
container, err := ac.GetContainerByID(ctx, suite.its.userID, "calendar") container, err := ac.GetContainerByID(ctx, suite.its.user.id, "calendar")
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
evts, err := ac.Stable. evts, err := ac.Stable.
Client(). Client().
Users(). Users().
ByUserId(suite.its.userID). ByUserId(suite.its.user.id).
Calendars(). Calendars().
ByCalendarId(ptr.Val(container.GetId())). ByCalendarId(ptr.Val(container.GetId())).
Events(). Events().
@ -63,7 +63,7 @@ func (suite *EventsPagerIntgSuite) TestEvents_GetItemsInContainerByCollisionKey(
results, err := suite.its.ac. results, err := suite.its.ac.
Events(). Events().
GetItemsInContainerByCollisionKey(ctx, suite.its.userID, "calendar") GetItemsInContainerByCollisionKey(ctx, suite.its.user.id, "calendar")
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result") require.Less(t, 0, len(results), "requires at least one result")

View File

@ -289,7 +289,7 @@ func (suite *EventsAPIIntgSuite) TestEvents_canFindNonStandardFolder() {
ac := suite.its.ac.Events() ac := suite.its.ac.Events()
rc := testdata.DefaultRestoreConfig("api_calendar_discovery") rc := testdata.DefaultRestoreConfig("api_calendar_discovery")
cal, err := ac.CreateContainer(ctx, suite.its.userID, "", rc.Location) cal, err := ac.CreateContainer(ctx, suite.its.user.id, "", rc.Location)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
var ( var (
@ -306,7 +306,7 @@ func (suite *EventsAPIIntgSuite) TestEvents_canFindNonStandardFolder() {
err = ac.EnumerateContainers( err = ac.EnumerateContainers(
ctx, ctx,
suite.its.userID, suite.its.user.id,
"Calendar", "Calendar",
findContainer, findContainer,
fault.New(true)) fault.New(true))
@ -342,7 +342,7 @@ func (suite *EventsAPIIntgSuite) TestEvents_GetContainerByName() {
_, err := suite.its.ac. _, err := suite.its.ac.
Events(). Events().
GetContainerByName(ctx, suite.its.userID, "", test.name) GetContainerByName(ctx, suite.its.user.id, "", test.name)
test.expectErr(t, err, clues.ToCore(err)) test.expectErr(t, err, clues.ToCore(err))
}) })
} }

View File

@ -112,7 +112,7 @@ func (suite *GroupsIntgSuite) TestGetAll() {
func (suite *GroupsIntgSuite) TestGroups_GetByID() { func (suite *GroupsIntgSuite) TestGroups_GetByID() {
var ( var (
groupID = suite.its.groupID groupID = suite.its.group.id
groupsAPI = suite.its.ac.Groups() groupsAPI = suite.its.ac.Groups()
) )

View File

@ -74,16 +74,19 @@ func parseableToMap(t *testing.T, thing serialization.Parsable) map[string]any {
// Suite Setup // Suite Setup
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type ids struct {
id string
driveID string
driveRootFolderID string
testContainerID string
}
type intgTesterSetup struct { type intgTesterSetup struct {
ac api.Client ac api.Client
gockAC api.Client gockAC api.Client
userID string user ids
userDriveID string site ids
userDriveRootFolderID string group ids
siteID string
siteDriveID string
siteDriveRootFolderID string
groupID string
} }
func newIntegrationTesterSetup(t *testing.T) intgTesterSetup { func newIntegrationTesterSetup(t *testing.T) intgTesterSetup {
@ -106,42 +109,47 @@ func newIntegrationTesterSetup(t *testing.T) intgTesterSetup {
// user drive // user drive
its.userID = tconfig.M365UserID(t) its.user.id = tconfig.M365UserID(t)
userDrive, err := its.ac.Users().GetDefaultDrive(ctx, its.userID) userDrive, err := its.ac.Users().GetDefaultDrive(ctx, its.user.id)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
its.userDriveID = ptr.Val(userDrive.GetId()) its.user.driveID = ptr.Val(userDrive.GetId())
userDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, its.userDriveID) userDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, its.user.driveID)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
its.userDriveRootFolderID = ptr.Val(userDriveRootFolder.GetId()) its.user.driveRootFolderID = ptr.Val(userDriveRootFolder.GetId())
its.siteID = tconfig.M365SiteID(t)
// site // site
siteDrive, err := its.ac.Sites().GetDefaultDrive(ctx, its.siteID) its.site.id = tconfig.M365SiteID(t)
siteDrive, err := its.ac.Sites().GetDefaultDrive(ctx, its.site.id)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
its.siteDriveID = ptr.Val(siteDrive.GetId()) its.site.driveID = ptr.Val(siteDrive.GetId())
siteDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, its.siteDriveID) siteDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, its.site.driveID)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
its.siteDriveRootFolderID = ptr.Val(siteDriveRootFolder.GetId()) its.site.driveRootFolderID = ptr.Val(siteDriveRootFolder.GetId())
// group // groups/teams
// use of the TeamID is intentional here, so that we are assured // use of the TeamID is intentional here, so that we are assured
// the group has full usage of the teams api. // the group has full usage of the teams api.
its.groupID = tconfig.M365TeamID(t) its.group.id = tconfig.M365TeamID(t)
team, err := its.ac.Groups().GetByID(ctx, its.groupID) channel, err := its.ac.Channels().
GetChannelByName(
ctx,
its.group.id,
"Test")
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
require.Equal(t, "Test", ptr.Val(channel.GetDisplayName()))
its.groupID = ptr.Val(team.GetId()) its.group.testContainerID = ptr.Val(channel.GetId())
return its return its
} }

View File

@ -17,46 +17,45 @@ import (
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type DeltaPager[T any] interface { type DeltaPager[T any] interface {
DeltaGetPager DeltaGetPager[T]
Resetter Resetter
SetNextLinker SetNextLinker
ValuesInPageLinker[T]
} }
type Pager[T any] interface { type Pager[T any] interface {
GetPager GetPager[T]
SetNextLinker SetNextLinker
ValuesInPageLinker[T]
} }
type DeltaGetPager interface { type DeltaGetPager[T any] interface {
GetPage(context.Context) (DeltaPageLinker, error) GetPage(context.Context) (DeltaLinkValuer[T], error)
} }
type GetPager interface { type GetPager[T any] interface {
GetPage(context.Context) (PageLinker, error) GetPage(context.Context) (LinkValuer[T], error)
} }
type Valuer[T any] interface { type Valuer[T any] interface {
GetValue() []T GetValue() []T
} }
type ValuesInPageLinker[T any] interface { type GetNextLinker interface {
ValuesIn(PageLinker) ([]T, error)
}
type PageLinker interface {
GetOdataNextLink() *string GetOdataNextLink() *string
} }
type DeltaPageLinker interface { type GetDeltaLinker interface {
PageLinker GetNextLinker
GetOdataDeltaLink() *string GetOdataDeltaLink() *string
} }
type PageLinkValuer[T any] interface { type LinkValuer[T any] interface {
PageLinker
Valuer[T] Valuer[T]
GetNextLinker
}
type DeltaLinkValuer[T any] interface {
LinkValuer[T]
GetDeltaLinker
} }
type SetNextLinker interface { type SetNextLinker interface {
@ -64,7 +63,7 @@ type SetNextLinker interface {
} }
type Resetter interface { type Resetter interface {
Reset(context.Context) Reset()
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -76,17 +75,17 @@ func IsNextLinkValid(next string) bool {
return !strings.Contains(next, `users//`) return !strings.Contains(next, `users//`)
} }
func NextLink(pl PageLinker) string { func NextLink(gnl GetNextLinker) string {
return ptr.Val(pl.GetOdataNextLink()) return ptr.Val(gnl.GetOdataNextLink())
} }
func NextAndDeltaLink(pl DeltaPageLinker) (string, string) { func NextAndDeltaLink(gdl GetDeltaLinker) (string, string) {
return NextLink(pl), ptr.Val(pl.GetOdataDeltaLink()) return NextLink(gdl), ptr.Val(gdl.GetOdataDeltaLink())
} }
// EmptyDeltaLinker is used to convert PageLinker to DeltaPageLinker // EmptyDeltaLinker is used to convert PageLinker to DeltaPageLinker
type EmptyDeltaLinker[T any] struct { type EmptyDeltaLinker[T any] struct {
PageLinkValuer[T] LinkValuer[T]
} }
func (EmptyDeltaLinker[T]) GetOdataDeltaLink() *string { func (EmptyDeltaLinker[T]) GetOdataDeltaLink() *string {
@ -94,23 +93,16 @@ func (EmptyDeltaLinker[T]) GetOdataDeltaLink() *string {
} }
func (e EmptyDeltaLinker[T]) GetValue() []T { func (e EmptyDeltaLinker[T]) GetValue() []T {
return e.PageLinkValuer.GetValue() return e.GetValue()
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// generic handler for non-delta item paging in a container // generic handler for non-delta item paging in a container
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type itemPager[T any] interface {
// getPage get a page with the specified options from graph
getPage(context.Context) (PageLinkValuer[T], error)
// setNext is used to pass in the next url got from graph
setNext(string)
}
func enumerateItems[T any]( func enumerateItems[T any](
ctx context.Context, ctx context.Context,
pager itemPager[T], pager Pager[T],
) ([]T, error) { ) ([]T, error) {
var ( var (
result = make([]T, 0) result = make([]T, 0)
@ -120,7 +112,7 @@ func enumerateItems[T any](
for len(nextLink) > 0 { for len(nextLink) > 0 {
// get the next page of data, check for standard errors // get the next page of data, check for standard errors
resp, err := pager.getPage(ctx) resp, err := pager.GetPage(ctx)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
} }
@ -128,7 +120,7 @@ func enumerateItems[T any](
result = append(result, resp.GetValue()...) result = append(result, resp.GetValue()...)
nextLink = NextLink(resp) nextLink = NextLink(resp)
pager.setNext(nextLink) pager.SetNext(nextLink)
} }
logger.Ctx(ctx).Infow("completed enumeration", "count", len(result)) logger.Ctx(ctx).Infow("completed enumeration", "count", len(result))
@ -137,9 +129,37 @@ func enumerateItems[T any](
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// generic handler for delta-based ittem paging in a container // generic handler for delta-based item paging in a container
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
func enumerateDeltaItems[T any](
ctx context.Context,
pager DeltaPager[T],
) ([]T, error) {
var (
result = make([]T, 0)
// stubbed initial value to ensure we enter the loop.
nextLink = "do-while"
)
for len(nextLink) > 0 {
// get the next page of data, check for standard errors
resp, err := pager.GetPage(ctx)
if err != nil {
return nil, graph.Stack(ctx, err)
}
result = append(result, resp.GetValue()...)
nextLink = NextLink(resp)
pager.SetNext(nextLink)
}
logger.Ctx(ctx).Infow("completed enumeration", "count", len(result))
return result, nil
}
// uses a models interface compliant with { GetValues() []T } // uses a models interface compliant with { GetValues() []T }
// to transform its results into a slice of getIDer interfaces. // to transform its results into a slice of getIDer interfaces.
// Generics used here to handle the variation of msoft interfaces // Generics used here to handle the variation of msoft interfaces
@ -173,16 +193,16 @@ type getIDAndAddtler interface {
GetAdditionalData() map[string]any GetAdditionalData() map[string]any
} }
func getAddedAndRemovedItemIDs( func getAddedAndRemovedItemIDs[T any](
ctx context.Context, ctx context.Context,
service graph.Servicer, service graph.Servicer,
pager DeltaPager[getIDAndAddtler], pager DeltaPager[T],
deltaPager DeltaPager[getIDAndAddtler], deltaPager DeltaPager[T],
oldDelta string, oldDelta string,
canMakeDeltaQueries bool, canMakeDeltaQueries bool,
) ([]string, []string, DeltaUpdate, error) { ) ([]string, []string, DeltaUpdate, error) {
var ( var (
pgr DeltaPager[getIDAndAddtler] pgr DeltaPager[T]
resetDelta bool resetDelta bool
) )
@ -211,7 +231,7 @@ func getAddedAndRemovedItemIDs(
} }
// reset deltaPager // reset deltaPager
pgr.Reset(ctx) pgr.Reset()
added, removed, deltaURL, err = getItemsAddedAndRemovedFromContainer(ctx, pgr) added, removed, deltaURL, err = getItemsAddedAndRemovedFromContainer(ctx, pgr)
if err != nil { if err != nil {
@ -222,9 +242,9 @@ func getAddedAndRemovedItemIDs(
} }
// generic controller for retrieving all item ids in a container. // generic controller for retrieving all item ids in a container.
func getItemsAddedAndRemovedFromContainer( func getItemsAddedAndRemovedFromContainer[T any](
ctx context.Context, ctx context.Context,
pager DeltaPager[getIDAndAddtler], pager DeltaPager[T],
) ([]string, []string, string, error) { ) ([]string, []string, string, error) {
var ( var (
addedIDs = []string{} addedIDs = []string{}
@ -243,10 +263,7 @@ func getItemsAddedAndRemovedFromContainer(
// each category type responds with a different interface, but all // each category type responds with a different interface, but all
// of them comply with GetValue, which is where we'll get our item data. // of them comply with GetValue, which is where we'll get our item data.
items, err := pager.ValuesIn(resp) items := resp.GetValue()
if err != nil {
return nil, nil, "", graph.Stack(ctx, err)
}
itemCount += len(items) itemCount += len(items)
page++ page++

View File

@ -57,41 +57,39 @@ func (v testPagerValue) GetAdditionalData() map[string]any {
// mock page // mock page
type testPage struct { type testPage[T any] struct {
values []any values []T
} }
func (p testPage) GetOdataNextLink() *string { func (p testPage[T]) GetOdataNextLink() *string {
// no next, just one page // no next, just one page
return ptr.To("") return ptr.To("")
} }
func (p testPage) GetOdataDeltaLink() *string { func (p testPage[T]) GetOdataDeltaLink() *string {
// delta is not tested here // delta is not tested here
return ptr.To("") return ptr.To("")
} }
func (p testPage) GetValue() []any { func (p testPage[T]) GetValue() []T {
return p.values return p.values
} }
// mock item pager // mock item pager
var _ itemPager[any] = &testPager{} var _ Pager[any] = &testPager{}
type testPager struct { type testPager struct {
t *testing.T t *testing.T
pager testPage pager testPage[any]
pageErr error pageErr error
} }
//lint:ignore U1000 False Positive func (p *testPager) GetPage(ctx context.Context) (LinkValuer[any], error) {
func (p *testPager) getPage(ctx context.Context) (PageLinkValuer[any], error) {
return p.pager, p.pageErr return p.pager, p.pageErr
} }
//lint:ignore U1000 False Positive func (p *testPager) SetNext(nextLink string) {}
func (p *testPager) setNext(nextLink string) {}
// mock id pager // mock id pager
@ -105,7 +103,7 @@ type testIDsPager struct {
needsReset bool needsReset bool
} }
func (p *testIDsPager) GetPage(ctx context.Context) (DeltaPageLinker, error) { func (p *testIDsPager) GetPage(ctx context.Context) (DeltaLinkValuer[getIDAndAddtler], error) {
if p.errorCode != "" { if p.errorCode != "" {
ierr := odataerrors.NewMainError() ierr := odataerrors.NewMainError()
ierr.SetCode(&p.errorCode) ierr.SetCode(&p.errorCode)
@ -116,10 +114,10 @@ func (p *testIDsPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
return nil, err return nil, err
} }
return testPage{}, nil return testPage[getIDAndAddtler]{}, nil
} }
func (p *testIDsPager) SetNext(string) {} func (p *testIDsPager) SetNext(string) {}
func (p *testIDsPager) Reset(context.Context) { func (p *testIDsPager) Reset() {
if !p.needsReset { if !p.needsReset {
require.Fail(p.t, "reset should not be called") require.Fail(p.t, "reset should not be called")
} }
@ -128,7 +126,7 @@ func (p *testIDsPager) Reset(context.Context) {
p.errorCode = "" p.errorCode = ""
} }
func (p *testIDsPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) { func (p *testIDsPager) ValuesIn(pl LinkValuer[getIDAndAddtler]) ([]getIDAndAddtler, error) {
items := []getIDAndAddtler{} items := []getIDAndAddtler{}
for _, id := range p.added { for _, id := range p.added {
@ -157,7 +155,7 @@ func TestItemPagerUnitSuite(t *testing.T) {
func (suite *ItemPagerUnitSuite) TestEnumerateItems() { func (suite *ItemPagerUnitSuite) TestEnumerateItems() {
tests := []struct { tests := []struct {
name string name string
getPager func(*testing.T, context.Context) itemPager[any] getPager func(*testing.T, context.Context) Pager[any]
expect []any expect []any
expectErr require.ErrorAssertionFunc expectErr require.ErrorAssertionFunc
}{ }{
@ -166,10 +164,10 @@ func (suite *ItemPagerUnitSuite) TestEnumerateItems() {
getPager: func( getPager: func(
t *testing.T, t *testing.T,
ctx context.Context, ctx context.Context,
) itemPager[any] { ) Pager[any] {
return &testPager{ return &testPager{
t: t, t: t,
pager: testPage{[]any{"foo", "bar"}}, pager: testPage[any]{[]any{"foo", "bar"}},
} }
}, },
expect: []any{"foo", "bar"}, expect: []any{"foo", "bar"},
@ -180,7 +178,7 @@ func (suite *ItemPagerUnitSuite) TestEnumerateItems() {
getPager: func( getPager: func(
t *testing.T, t *testing.T,
ctx context.Context, ctx context.Context,
) itemPager[any] { ) Pager[any] {
return &testPager{ return &testPager{
t: t, t: t,
pageErr: assert.AnError, pageErr: assert.AnError,

View File

@ -41,7 +41,7 @@ func (suite *ListsAPIIntgSuite) TestLists_PostDrive() {
var ( var (
acl = suite.its.ac.Lists() acl = suite.its.ac.Lists()
driveName = testdata.DefaultRestoreConfig("list_api_post_drive").Location driveName = testdata.DefaultRestoreConfig("list_api_post_drive").Location
siteID = suite.its.siteID siteID = suite.its.site.id
) )
// first post, should have no errors // first post, should have no errors

View File

@ -31,7 +31,7 @@ func (c Mail) NewMailFolderPager(userID string) mailFolderPager {
return mailFolderPager{c.Stable, builder} return mailFolderPager{c.Stable, builder}
} }
func (p *mailFolderPager) getPage(ctx context.Context) (PageLinker, error) { func (p *mailFolderPager) getPage(ctx context.Context) (LinkValuer[models.MailFolderable], error) {
page, err := p.builder.Get(ctx, nil) page, err := p.builder.Get(ctx, nil)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
@ -44,7 +44,7 @@ func (p *mailFolderPager) setNext(nextLink string) {
p.builder = users.NewItemMailFoldersRequestBuilder(nextLink, p.service.Adapter()) p.builder = users.NewItemMailFoldersRequestBuilder(nextLink, p.service.Adapter())
} }
func (p *mailFolderPager) valuesIn(pl PageLinker) ([]models.MailFolderable, error) { func (p *mailFolderPager) valuesIn(pl LinkValuer[models.MailFolderable]) ([]models.MailFolderable, error) {
// Ideally this should be `users.ItemMailFoldersResponseable`, but // Ideally this should be `users.ItemMailFoldersResponseable`, but
// that is not a thing as stable returns different result // that is not a thing as stable returns different result
page, ok := pl.(models.MailFolderCollectionResponseable) page, ok := pl.(models.MailFolderCollectionResponseable)
@ -79,10 +79,7 @@ func (c Mail) EnumerateContainers(
return graph.Stack(ctx, err) return graph.Stack(ctx, err)
} }
resp, err := pgr.valuesIn(page) resp := page.GetValue()
if err != nil {
return graph.Stack(ctx, err)
}
for _, fold := range resp { for _, fold := range resp {
if el.Failure() != nil { if el.Failure() != nil {
@ -121,7 +118,7 @@ func (c Mail) EnumerateContainers(
// item pager // item pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemPager[models.Messageable] = &mailPageCtrl{} var _ Pager[models.Messageable] = &mailPageCtrl{}
type mailPageCtrl struct { type mailPageCtrl struct {
gs graph.Servicer gs graph.Servicer
@ -132,7 +129,7 @@ type mailPageCtrl struct {
func (c Mail) NewMailPager( func (c Mail) NewMailPager(
userID, containerID string, userID, containerID string,
selectProps ...string, selectProps ...string,
) itemPager[models.Messageable] { ) Pager[models.Messageable] {
options := &users.ItemMailFoldersItemMessagesRequestBuilderGetRequestConfiguration{ options := &users.ItemMailFoldersItemMessagesRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize)), Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize)),
QueryParameters: &users.ItemMailFoldersItemMessagesRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemMailFoldersItemMessagesRequestBuilderGetQueryParameters{
@ -155,14 +152,11 @@ func (c Mail) NewMailPager(
return &mailPageCtrl{c.Stable, builder, options} return &mailPageCtrl{c.Stable, builder, options}
} }
//lint:ignore U1000 False Positive func (p *mailPageCtrl) GetPage(
func (p *mailPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.Messageable], error) { ctx context.Context,
) (LinkValuer[models.Messageable], error) {
page, err := p.builder.Get(ctx, p.options) page, err := p.builder.Get(ctx, p.options)
if err != nil { return EmptyDeltaLinker[models.Messageable]{LinkValuer: page}, graph.Stack(ctx, err).OrNil()
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.Messageable]{PageLinkValuer: page}, nil
} }
//lint:ignore U1000 False Positive //lint:ignore U1000 False Positive
@ -206,13 +200,9 @@ func (c Mail) NewMailIDsPager(
return &mailIDPager{c.Stable, builder, config} return &mailIDPager{c.Stable, builder, config}
} }
func (p *mailIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) { func (p *mailIDPager) GetPage(ctx context.Context) (DeltaLinkValuer[models.Messageable], error) {
page, err := p.builder.Get(ctx, p.options) page, err := p.builder.Get(ctx, p.options)
if err != nil { return EmptyDeltaLinker[models.Messageable]{LinkValuer: page}, graph.Stack(ctx, err).OrNil()
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.Messageable]{PageLinkValuer: page}, nil
} }
func (p *mailIDPager) SetNext(nextLink string) { func (p *mailIDPager) SetNext(nextLink string) {
@ -220,11 +210,7 @@ func (p *mailIDPager) SetNext(nextLink string) {
} }
// non delta pagers don't have reset // non delta pagers don't have reset
func (p *mailIDPager) Reset(context.Context) {} func (p *mailIDPager) Reset() {}
func (p *mailIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Messageable](pl)
}
func (c Mail) GetItemsInContainerByCollisionKey( func (c Mail) GetItemsInContainerByCollisionKey(
ctx context.Context, ctx context.Context,
@ -256,7 +242,7 @@ func (c Mail) GetItemIDsInContainer(
items, err := enumerateItems(ctx, pager) items, err := enumerateItems(ctx, pager)
if err != nil { if err != nil {
return nil, graph.Wrap(ctx, err, "enumerating contacts") return nil, graph.Wrap(ctx, err, "enumerating mail messages")
} }
m := map[string]struct{}{} m := map[string]struct{}{}
@ -324,7 +310,7 @@ func (c Mail) NewMailDeltaIDsPager(
return &mailDeltaIDPager{c.Stable, userID, containerID, builder, config} return &mailDeltaIDPager{c.Stable, userID, containerID, builder, config}
} }
func (p *mailDeltaIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) { func (p *mailDeltaIDPager) GetPage(ctx context.Context) (LinkValuer[models.Messageable], error) {
page, err := p.builder.Get(ctx, p.options) page, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
@ -337,7 +323,7 @@ func (p *mailDeltaIDPager) SetNext(nextLink string) {
p.builder = users.NewItemMailFoldersItemMessagesDeltaRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemMailFoldersItemMessagesDeltaRequestBuilder(nextLink, p.gs.Adapter())
} }
func (p *mailDeltaIDPager) Reset(ctx context.Context) { func (p *mailDeltaIDPager) Reset() {
p.builder = p.gs. p.builder = p.gs.
Client(). Client().
Users(). Users().
@ -348,10 +334,6 @@ func (p *mailDeltaIDPager) Reset(ctx context.Context) {
Delta() Delta()
} }
func (p *mailDeltaIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Messageable](pl)
}
func (c Mail) GetAddedAndRemovedItemIDs( func (c Mail) GetAddedAndRemovedItemIDs(
ctx context.Context, ctx context.Context,
userID, containerID, oldDelta string, userID, containerID, oldDelta string,

View File

@ -40,13 +40,13 @@ func (suite *MailPagerIntgSuite) TestMail_GetItemsInContainerByCollisionKey() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
container, err := ac.GetContainerByID(ctx, suite.its.userID, api.MailInbox) container, err := ac.GetContainerByID(ctx, suite.its.user.id, api.MailInbox)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
msgs, err := ac.Stable. msgs, err := ac.Stable.
Client(). Client().
Users(). Users().
ByUserId(suite.its.userID). ByUserId(suite.its.user.id).
MailFolders(). MailFolders().
ByMailFolderId(ptr.Val(container.GetId())). ByMailFolderId(ptr.Val(container.GetId())).
Messages(). Messages().
@ -62,7 +62,7 @@ func (suite *MailPagerIntgSuite) TestMail_GetItemsInContainerByCollisionKey() {
expect := maps.Keys(expectM) expect := maps.Keys(expectM)
results, err := suite.its.ac.Mail().GetItemsInContainerByCollisionKey(ctx, suite.its.userID, api.MailInbox) results, err := suite.its.ac.Mail().GetItemsInContainerByCollisionKey(ctx, suite.its.user.id, api.MailInbox)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result") require.Less(t, 0, len(results), "requires at least one result")
@ -101,7 +101,7 @@ func (suite *MailPagerIntgSuite) TestMail_GetItemsIDsInContainer() {
msgs, err := ac.Stable. msgs, err := ac.Stable.
Client(). Client().
Users(). Users().
ByUserId(suite.its.userID). ByUserId(suite.its.user.id).
MailFolders(). MailFolders().
ByMailFolderId(api.MailInbox). ByMailFolderId(api.MailInbox).
Messages(). Messages().
@ -116,7 +116,7 @@ func (suite *MailPagerIntgSuite) TestMail_GetItemsIDsInContainer() {
} }
results, err := suite.its.ac.Mail(). results, err := suite.its.ac.Mail().
GetItemIDsInContainer(ctx, suite.its.userID, api.MailInbox) GetItemIDsInContainer(ctx, suite.its.user.id, api.MailInbox)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result") require.Less(t, 0, len(results), "requires at least one result")
require.Equal(t, len(expect), len(results), "must have same count of items") require.Equal(t, len(expect), len(results), "must have same count of items")

View File

@ -414,7 +414,7 @@ func (suite *MailAPIIntgSuite) TestMail_GetContainerByName() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
parent, err := acm.CreateContainer(ctx, suite.its.userID, "msgfolderroot", rc.Location) parent, err := acm.CreateContainer(ctx, suite.its.user.id, "msgfolderroot", rc.Location)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
table := []struct { table := []struct {
@ -448,7 +448,7 @@ func (suite *MailAPIIntgSuite) TestMail_GetContainerByName() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
_, err := acm.GetContainerByName(ctx, suite.its.userID, test.parentContainerID, test.name) _, err := acm.GetContainerByName(ctx, suite.its.user.id, test.parentContainerID, test.name)
test.expectErr(t, err, clues.ToCore(err)) test.expectErr(t, err, clues.ToCore(err))
}) })
} }
@ -460,10 +460,10 @@ func (suite *MailAPIIntgSuite) TestMail_GetContainerByName() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
child, err := acm.CreateContainer(ctx, suite.its.userID, pid, rc.Location) child, err := acm.CreateContainer(ctx, suite.its.user.id, pid, rc.Location)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
result, err := acm.GetContainerByName(ctx, suite.its.userID, pid, rc.Location) result, err := acm.GetContainerByName(ctx, suite.its.user.id, pid, rc.Location)
assert.NoError(t, err, clues.ToCore(err)) assert.NoError(t, err, clues.ToCore(err))
assert.Equal(t, ptr.Val(child.GetId()), ptr.Val(result.GetId())) assert.Equal(t, ptr.Val(child.GetId()), ptr.Val(result.GetId()))
}) })

View File

@ -8,26 +8,25 @@ import (
"github.com/alcionai/corso/src/pkg/services/m365/api" "github.com/alcionai/corso/src/pkg/services/m365/api"
) )
type DeltaNextLinks struct {
Next *string
Delta *string
}
func (dnl *DeltaNextLinks) GetOdataNextLink() *string {
return dnl.Next
}
func (dnl *DeltaNextLinks) GetOdataDeltaLink() *string {
return dnl.Delta
}
type PagerResult[T any] struct { type PagerResult[T any] struct {
Values []T
NextLink *string
DeltaLink *string DeltaLink *string
NextLink *string
Values []T
Err error Err error
} }
func (pr PagerResult[T]) GetValue() []T {
return pr.Values
}
func (pr PagerResult[T]) GetOdataNextLink() *string {
return pr.NextLink
}
func (pr PagerResult[T]) GetOdataDeltaLink() *string {
return pr.DeltaLink
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// non-delta pager // non-delta pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -37,7 +36,7 @@ type Pager[T any] struct {
getIdx int getIdx int
} }
func (p *Pager[T]) GetPage(context.Context) (api.PageLinker, error) { func (p *Pager[T]) GetPage(context.Context) (api.LinkValuer[T], error) {
if len(p.ToReturn) <= p.getIdx { if len(p.ToReturn) <= p.getIdx {
return nil, clues.New("index out of bounds"). return nil, clues.New("index out of bounds").
With("index", p.getIdx, "values", p.ToReturn) With("index", p.getIdx, "values", p.ToReturn)
@ -46,28 +45,11 @@ func (p *Pager[T]) GetPage(context.Context) (api.PageLinker, error) {
idx := p.getIdx idx := p.getIdx
p.getIdx++ p.getIdx++
link := DeltaNextLinks{Next: p.ToReturn[idx].NextLink} return &p.ToReturn[idx], p.ToReturn[idx].Err
return &link, p.ToReturn[idx].Err
} }
func (p *Pager[T]) SetNext(string) {} func (p *Pager[T]) SetNext(string) {}
func (p *Pager[T]) ValuesIn(api.PageLinker) ([]T, error) {
idx := p.getIdx
if idx > 0 {
// Return values lag by one since we increment in GetPage().
idx--
}
if len(p.ToReturn) <= idx {
return nil, clues.New("index out of bounds").
With("index", idx, "values", p.ToReturn)
}
return p.ToReturn[idx].Values, nil
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// delta pager // delta pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -77,7 +59,7 @@ type DeltaPager[T any] struct {
getIdx int getIdx int
} }
func (p *DeltaPager[T]) GetPage(context.Context) (api.DeltaPageLinker, error) { func (p *DeltaPager[T]) GetPage(context.Context) (api.DeltaLinkValuer[T], error) {
if len(p.ToReturn) <= p.getIdx { if len(p.ToReturn) <= p.getIdx {
return nil, clues.New("index out of bounds"). return nil, clues.New("index out of bounds").
With("index", p.getIdx, "values", p.ToReturn) With("index", p.getIdx, "values", p.ToReturn)
@ -86,28 +68,8 @@ func (p *DeltaPager[T]) GetPage(context.Context) (api.DeltaPageLinker, error) {
idx := p.getIdx idx := p.getIdx
p.getIdx++ p.getIdx++
link := DeltaNextLinks{ return &p.ToReturn[idx], p.ToReturn[idx].Err
Next: p.ToReturn[idx].NextLink,
Delta: p.ToReturn[idx].DeltaLink,
}
return &link, p.ToReturn[idx].Err
} }
func (p *DeltaPager[T]) SetNext(string) {} func (p *DeltaPager[T]) SetNext(string) {}
func (p *DeltaPager[T]) Reset(context.Context) {} func (p *DeltaPager[T]) Reset() {}
func (p *DeltaPager[T]) ValuesIn(api.PageLinker) ([]T, error) {
idx := p.getIdx
if idx > 0 {
// Return values lag by one since we increment in GetPage().
idx--
}
if len(p.ToReturn) <= idx {
return nil, clues.New("index out of bounds").
With("index", idx, "values", p.ToReturn)
}
return p.ToReturn[idx].Values, nil
}