@@ -2424,12 +2424,12 @@ def uid_search(...)
24242424 # {[RFC7162]}[https://tools.ietf.org/html/rfc7162] in order to use the
24252425 # +changedsince+ argument. Using +changedsince+ implicitly enables the
24262426 # +CONDSTORE+ extension.
2427- def fetch ( set , attr , mod = nil , changedsince : nil )
2428- fetch_internal ( "FETCH" , set , attr , mod , changedsince : changedsince )
2427+ def fetch ( ... )
2428+ fetch_internal ( "FETCH" , ... )
24292429 end
24302430
24312431 # :call-seq:
2432- # uid_fetch(set, attr, changedsince: nil) -> array of FetchData
2432+ # uid_fetch(set, attr, changedsince: nil, partial: nil ) -> array of FetchData
24332433 #
24342434 # Sends a {UID FETCH command [IMAP4rev1 §6.4.8]}[https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8]
24352435 # to retrieve data associated with a message in the mailbox.
@@ -2446,13 +2446,44 @@ def fetch(set, attr, mod = nil, changedsince: nil)
24462446 #
24472447 # +changedsince+ (optional) behaves the same as with #fetch.
24482448 #
2449+ # +partial+ is an optional range to limit the number of results returned.
2450+ # It's useful when +set+ contains an unknown number of messages.
2451+ # <tt>1..500</tt> returns the first 500 messages in +set+ (in mailbox
2452+ # order), <tt>501..1000</tt> the second 500, and so on. +partial+ may also
2453+ # be negative: <tt>-500..-1</tt> selects the last 500 messages in +set+.
2454+ # <em>Requires the +PARTIAL+ capabability.</em>
2455+ # {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394]
2456+ #
2457+ # For example:
2458+ #
2459+ # # Without partial, the size of the results may be unknown beforehand:
2460+ # results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS))
2461+ # # ... maybe wait for a long time ... and allocate a lot of memory ...
2462+ # results.size # => 0..2**32-1
2463+ # process results # may also take a long time and use a lot of memory...
2464+ #
2465+ # # Using partial, the results may be paginated:
2466+ # loop do
2467+ # results = imap.uid_fetch(next_uid_to_fetch.., %w(UID FLAGS),
2468+ # partial: 1..500)
2469+ # # fetch should return quickly and allocate little memory
2470+ # results.size # => 0..500
2471+ # break if results.empty?
2472+ # next_uid_to_fetch = results.last.uid + 1
2473+ # process results
2474+ # end
2475+ #
24492476 # Related: #fetch, FetchData
24502477 #
24512478 # ==== Capabilities
24522479 #
2453- # Same as #fetch.
2454- def uid_fetch ( set , attr , mod = nil , changedsince : nil )
2455- fetch_internal ( "UID FETCH" , set , attr , mod , changedsince : changedsince )
2480+ # The server's capabilities must include +PARTIAL+
2481+ # {[RFC9394]}[https://rfc-editor.org/rfc/rfc9394] in order to use the
2482+ # +partial+ argument.
2483+ #
2484+ # Otherwise, the same as #fetch.
2485+ def uid_fetch ( ...)
2486+ fetch_internal ( "UID FETCH" , ...)
24562487 end
24572488
24582489 # :call-seq:
@@ -3398,7 +3429,12 @@ def search_internal(cmd, ...)
33983429 end
33993430 end
34003431
3401- def fetch_internal ( cmd , set , attr , mod = nil , changedsince : nil )
3432+ def fetch_internal ( cmd , set , attr , mod = nil , partial : nil , changedsince : nil )
3433+ set = SequenceSet [ set ]
3434+ if partial
3435+ mod ||= [ ]
3436+ mod << "PARTIAL" << PartialRange [ partial ]
3437+ end
34023438 if changedsince
34033439 mod ||= [ ]
34043440 mod << "CHANGEDSINCE" << Integer ( changedsince )
@@ -3415,9 +3451,9 @@ def fetch_internal(cmd, set, attr, mod = nil, changedsince: nil)
34153451 synchronize do
34163452 clear_responses ( "FETCH" )
34173453 if mod
3418- send_command ( cmd , SequenceSet . new ( set ) , attr , mod )
3454+ send_command ( cmd , set , attr , mod )
34193455 else
3420- send_command ( cmd , SequenceSet . new ( set ) , attr )
3456+ send_command ( cmd , set , attr )
34213457 end
34223458 clear_responses ( "FETCH" )
34233459 end
0 commit comments