Slide 1

Slide 1 text

 1 *UFSBUPSͰϖʔδωʔγϣϯΛ࣮ݱ͢Δ (PͷΠςϨʔλਂງΓ/JHIU !TPOBUBSEͦͳଠגࣜձࣾ4UBDL

Slide 2

Slide 2 text

2 *UFSBUPSͷ࢖͍ॴ w NBQ fi MUFSʜTMJDFपΓͰ࢖͑ͦ͏ w ˠͳΜͱͳ͘Θ͔Δ w ଞʹ͸ʁ

Slide 3

Slide 3 text

3 %#ͷϖʔδωʔγϣϯΛߟ͑ͯΈΔ w TQBOOFSDQBDLBHFͰ$MPVE4QBOOFSͷૢ࡞Λϥοϓ͍ͯ͠Δ w ҎԼ͸*UFSBUPSΛ࢖͏લͷίʔυ cursorInfo = offset.NewCursorInfo() for { stmt := statement.ByCursor[domain.User](cursorInfo) users, pageInfo, err := spannerc.GetMulti(ctx, stmt) if err != nil { return nil, nil, fmt.Errorf(": %w", err) } // usersʹԿ͔͠Βͷॲཧ if !pageInfo.HasNextPage { break } cursorInfo.Cursor = pageInfo.EndCursor }

Slide 4

Slide 4 text

4 cursorInfo := offset.NewCursorInfo() for { stmt := statement.ByCursor[domain.User](cursorInfo) users, pageInfo, err := spannerc.GetMulti(ctx, stmt) if err != nil { return nil, nil, fmt.Errorf(": %w", err) } // usersʹԿ͔͠Βͷॲཧ if !pageInfo.HasNextPage { break } cursorInfo.Cursor = pageInfo.EndCursor } ࣍ͷϖʔδ͕ͳ͚Ε͹GPS͔Βൈ͚Δ ࣍ͷϖʔδͷ$VSTPSΛߋ৽͢Δ

Slide 5

Slide 5 text

5 cursorInfo := offset.NewCursorInfo() for { stmt := statement.ByCursor[domain.User](cursorInfo) users, pageInfo, err := spannerc.GetMulti(ctx, stmt) if err != nil { return nil, nil, fmt.Errorf(": %w", err) } // usersʹԿ͔͠Βͷॲཧ if !pageInfo.HasNextPage { break } cursorInfo.Cursor = pageInfo.EndCursor } CSFBLΛ๨ΕͨΓɺ৚݅Λؒҧ͑Δ

Slide 6

Slide 6 text

6 cursorInfo := offset.NewCursorInfo() for { stmt := statement.ByCursor[domain.User](cursorInfo) users, pageInfo, err := spannerc.GetMulti(ctx, stmt) if err != nil { return nil, nil, fmt.Errorf(": %w", err) } // usersʹԿ͔͠Βͷॲཧ if !pageInfo.HasNextPage { break } // cursorInfo.Cursor = pageInfo.EndCursor } $VSTPSͷߋ৽Λ๨ΕΔ

Slide 7

Slide 7 text

7 cursorInfo := offset.NewCursorInfo() for { stmt := statement.ByCursor[domain.User](cursorInfo) users, pageInfo, err := spannerc.GetMulti(ctx, stmt) if err != nil { return nil, nil, fmt.Errorf(": %w", err) } // usersʹԿ͔͠Βͷॲཧ if users.Invalid() { continue } if !pageInfo.HasNextPage { break } cursorInfo.Cursor = pageInfo.EndCursor } $VSTPSͷߋ৽Λ๨ΕͯDPOUJOVF

Slide 8

Slide 8 text

8 cursorInfo := offset.NewCursorInfo() for { stmt := statement.ByCursor[domain.User](cursorInfo) users, pageInfo, err := spannerc.GetMulti(ctx, stmt) if err != nil { return nil, nil, fmt.Errorf(": %w", err) } // usersʹԿ͔͠Βͷॲཧ if users.Invalid() { continue } if !pageInfo.HasNextPage { break } cursorInfo.Cursor = pageInfo.EndCursor } ࠓ·Ͱ͸ՄೳͳൣғͰ-JOUͰରԠ͍ͯͨ͠

Slide 9

Slide 9 text

9 stmt := statement.ByCursor[domain.User](offset.NewCursorInfo()) for users, err := range spannerc.GetMultiIter(ctx, stmt) { if err != nil { return nil, nil, fmt.Errorf(": %w", err) } // usersʹԿ͔͠Βͷॲཧ if users.Invalid() { continue } } ϧʔϓͷϖʔδωʔγϣϯॲཧ΍ऴྃ৚݅ (FU.VMUJ*UFSʹӅṭ͞Ε͍ͯΔ 6TFSʹؔ࿈͢ΔॲཧͷΈΛॻ͚͹Α͘ͳͬͨ QBHF*OGPม਺΁ͷΞΫηε͕ෆཁʹͳͬͨ

Slide 10

Slide 10 text

10 func GetMultiIter[T any](ctx context.Context, stmt offset.StatementWithCursor[T]) iter.Seq2[[]*T, error] { return func(yield func([]*T, error) bool) { for { stmt.Statement.Params["offset"] = stmt.CursorInfo.Offset() ts, pageInfo, err := GetMulti[T](ctx, stmt) if !yield(ts, err) { return } if err != nil { return } if !pageInfo.HasNextPage { break } stmt.CursorInfo.Cursor = pageInfo.EndCursor } } } (FU.VMUJ*UFSͷ࣮૷

Slide 11

Slide 11 text

11 for users, err := range statement.ByCursor[domain.User](offset.NewCursorInfo()).All(ctx) { if err != nil { return nil, nil, fmt.Errorf(": %w", err) } // usersʹԿ͔͠Βͷॲཧ if users.Invalid() { continue } } ͓·͚ ͜Μͳ࣮૷ʹͨ͠ΒΑΓ(Pͷ*UFSBUPSΒ͍͠

Slide 12

Slide 12 text

12 *UFSBUPSͷ࢖͍ॴ w ·ͱΊ w ϧʔϓΛந৅Խ͢Δ༻్Ͱ࢖͑Δ w 'PSͷதͰ͋Δ৚݅ͰCSFBL΍DPOUJOVFΛ͍ͯ͠ΔͷͰ͋Ε͹γϯϓϧʹͰ͖Δ w Ͳ͜·Ͱ*UFSBUPSʹ͍ͯ͘͠ʁ w *UFSBUPS͸௚ײతʹಡΈͮΒ͍ͷͰɺͪΐͬͱͨ͜͠ͱͰ*UFSBUPSΛ࢖͍͗͢Δͱٯʹ ίʔυ͕ಡΈͮΒ͘ͳΔ͔΋ w ϧʔϓʹ໌֬ͳ՝୊͕͋Δɺ৑௕ͳॲཧΛ͍ͭ΋࣮૷͠ͳ͚Ε͹ͳΒͳ͍৔߹ͳͲɺ ༻๏༻ྔΛकͬͯਖ਼͓͘͠࢖͍͍ͩ͘͞ɻ

Slide 13

Slide 13 text

13 *UFSBUPSͷ࢖͍ॴ w ͓·͚ w %BUBCBTFपลͰ͸EBUBCBTFTRMQBDLBHFͳͲͰJP&0'ͳͲͷϋϯυϦϯά΋*UFSBUPS ͰෆཁʹͰ͖Δ w JP3FBEFSͳͲ΋ಉ༷ʁ w ͔͠͠JPQBDLBHFͷΠϯλʔϑΣʔε͕มΘΔͷ͸؆୯Ͱ͸ͳͦ͞͏ w ࠓޙඪ४ϥΠϒϥϦ͕ͲͷΑ͏ʹ*UFSBUPSʹରԠ͍͔ͯ͘͠΋ཁ஫໨