Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Iteratorでページネーションを実現する
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
sonatard
September 24, 2024
Programming
1.4k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Iteratorでページネーションを実現する
sonatard
September 24, 2024
More Decks by sonatard
See All by sonatard
Shopifyアプリ開発における Shopifyの機能活用
sonatard
4
600
Goのエラースタックトレースの歴史と今後
sonatard
19
17k
Go 1.22のEnhanced ServeMux chiから移行できるのか?
sonatard
5
700
GraphQL実践ノウハウv2
sonatard
17
3.1k
プロトコル、インターフェースとしてのGraphQL
sonatard
4
2.3k
GraphQL実践ノウハウ/graphql-knowhow
sonatard
41
12k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Go1.18から導入されるnetip package/netip-package
sonatard
3
1.3k
Jetpack ComposeとGraphQLによるServer Driven UI/jetpackcompose-grahpql-serverdrivernui
sonatard
1
2k
Other Decks in Programming
See All in Programming
Oxlintのカスタムルールの現況
syumai
6
1.1k
JavaDoc 再入門
nagise
1
380
エンジニアと一緒にテストコードの設計と実装を改善した話
mototakatsu
0
210
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.8k
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
350k
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
270
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
350
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.4k
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
7.4k
Claspは野良GASの夢をみるか
takter00
0
200
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
200
Featured
See All Featured
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
750
A Tale of Four Properties
chriscoyier
163
24k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
The untapped power of vector embeddings
frankvandijk
2
1.8k
Embracing the Ebb and Flow
colly
88
5.1k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
310
Odyssey Design
rkendrick25
PRO
2
700
WCS-LA-2024
lcolladotor
0
650
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
Transcript
 1 *UFSBUPSͰϖʔδωʔγϣϯΛ࣮ݱ͢Δ (PͷΠςϨʔλਂງΓ/JHIU !TPOBUBSEͦͳଠגࣜձࣾ4UBDL
2 *UFSBUPSͷ͍ॴ w NBQ fi MUFSʜTMJDFपΓͰ͑ͦ͏ w ˠͳΜͱͳ͘Θ͔Δ w
ଞʹʁ
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 }
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Λߋ৽͢Δ
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ΛΕͨΓɺ݅Λؒҧ͑Δ
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ͷߋ৽ΛΕΔ
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
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ͰରԠ͍ͯͨ͠
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มͷΞΫηε͕ෆཁʹͳͬͨ
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ͷ࣮
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Β͍͠
12 *UFSBUPSͷ͍ॴ w ·ͱΊ w ϧʔϓΛநԽ͢Δ༻్Ͱ͑Δ w 'PSͷதͰ͋Δ݅ͰCSFBLDPOUJOVFΛ͍ͯ͠ΔͷͰ͋ΕγϯϓϧʹͰ͖Δ w Ͳ͜·Ͱ*UFSBUPSʹ͍ͯ͘͠ʁ
w *UFSBUPSײతʹಡΈͮΒ͍ͷͰɺͪΐͬͱͨ͜͠ͱͰ*UFSBUPSΛ͍͗͢Δͱٯʹ ίʔυ͕ಡΈͮΒ͘ͳΔ͔ w ϧʔϓʹ໌֬ͳ՝͕͋ΔɺͳॲཧΛ͍࣮ͭ͠ͳ͚ΕͳΒͳ͍߹ͳͲɺ ༻๏༻ྔΛकͬͯਖ਼͓͍͍ͩ͘͘͠͞ɻ
13 *UFSBUPSͷ͍ॴ w ͓·͚ w %BUBCBTFपลͰEBUBCBTFTRMQBDLBHFͳͲͰJP&0'ͳͲͷϋϯυϦϯά*UFSBUPS ͰෆཁʹͰ͖Δ w JP3FBEFSͳͲಉ༷ʁ w
͔͠͠JPQBDLBHFͷΠϯλʔϑΣʔε͕มΘΔͷ؆୯Ͱͳͦ͞͏ w ࠓޙඪ४ϥΠϒϥϦ͕ͲͷΑ͏ʹ*UFSBUPSʹରԠ͍͔ͯ͘͠ཁ