Skip to content

Commit 654d97a

Browse files
authored
Merge pull request #323 from velimir/stream-get-bucket-object-versions
add streaming support for list_object_versions
2 parents 39c2129 + b76739d commit 654d97a

File tree

3 files changed

+289
-105
lines changed

3 files changed

+289
-105
lines changed

lib/ex_aws/s3.ex

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,39 @@ defmodule ExAws.S3 do
229229
)
230230
end
231231

232-
@doc "List metadata about all versions of the objects in a bucket."
232+
@type list_object_versions_opts :: [
233+
{:delimiter, binary}
234+
| {:key_marker, binary}
235+
| {:version_id_marker, binary}
236+
| {:max_keys, 0..1000}
237+
| {:prefix, binary}
238+
| {:encoding_type, binary}
239+
]
240+
241+
@doc """
242+
List metadata about all versions of the objects in a bucket.
243+
244+
Can be streamed.
245+
246+
## Examples
247+
```
248+
S3.list_object_versions("my-bucket") |> ExAws.request
249+
250+
S3.list_object_versions("my-bucket") |> ExAws.stream!
251+
S3.list_object_versions("my-bucket", prefix: "backup/") |> ExAws.stream!
252+
```
253+
"""
233254
@spec list_object_versions(bucket :: binary) :: ExAws.Operation.S3.t()
234-
@spec list_object_versions(bucket :: binary, opts :: Keyword.t()) ::
255+
@spec list_object_versions(bucket :: binary, opts :: list_object_versions_opts) ::
235256
ExAws.Operation.S3.t()
257+
@params [:delimiter, :key_marker, :version_id_marker, :max_keys, :prefix, :encoding_type]
236258
def list_object_versions(bucket, opts \\ []) do
237-
request(:get, bucket, "/", [resource: "versions", params: opts],
259+
params =
260+
opts
261+
|> format_and_take(@params)
262+
263+
request(:get, bucket, "/", [resource: "versions", params: params],
264+
stream_builder: &ExAws.S3.Lazy.stream_object_versions!(bucket, opts, &1),
238265
parser: &ExAws.S3.Parsers.parse_object_versions/1
239266
)
240267
end

lib/ex_aws/s3/lazy.ex

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,37 @@ defmodule ExAws.S3.Lazy do
5454
)
5555
end
5656

57+
def stream_object_versions!(bucket, opts, config) do
58+
request_fun = fn fun_opts ->
59+
ExAws.S3.list_object_versions(bucket, Keyword.merge(opts, fun_opts))
60+
|> ExAws.request!(config)
61+
|> Map.get(:body)
62+
end
63+
64+
Stream.resource(
65+
fn -> {request_fun, []} end,
66+
fn
67+
:quit ->
68+
{:halt, nil}
69+
70+
{fun, args} ->
71+
case fun.(args) do
72+
results = %{is_truncated: "true"} ->
73+
{add_version_results(results),
74+
{fun,
75+
[
76+
key_marker: results[:next_key_marker],
77+
version_id_marker: results[:next_version_id_marker]
78+
]}}
79+
80+
results ->
81+
{add_version_results(results), :quit}
82+
end
83+
end,
84+
& &1
85+
)
86+
end
87+
5788
def add_results(results, opts) do
5889
case Keyword.get(opts, :stream_prefixes, nil) do
5990
nil -> results.contents
@@ -68,4 +99,8 @@ defmodule ExAws.S3.Lazy do
6899
end
69100

70101
def next_marker(%{next_marker: marker}), do: marker
102+
103+
def add_version_results(results) do
104+
(results[:versions] || []) ++ (results[:delete_markers] || [])
105+
end
71106
end

0 commit comments

Comments
 (0)