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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
0
160
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
240
Vite+ Unified Toolchain for the Web
naokihaba
0
360
Agentic UI
manfredsteyer
PRO
0
200
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
970
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
220
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
230
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
170
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
これからAgentCoreを触る方へトレンドはGatewayです
har1101
2
320
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
14
6.4k
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
200
Featured
See All Featured
A Tale of Four Properties
chriscoyier
163
24k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
320
How to Talk to Developers About Accessibility
jct
2
260
First, design no harm
axbom
PRO
2
1.2k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
400
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.5k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
470
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
240
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.3k
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ʹରԠ͍͔ͯ͘͠ཁ