Skip to content

Commit dab8a1f

Browse files
committed
feat: Add get_record!/1,2
1 parent cc1ca8f commit dab8a1f

File tree

4 files changed

+74
-8
lines changed

4 files changed

+74
-8
lines changed

lib/file_cache.ex

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ defmodule FileCache do
137137
do_get!(validate_id!(id), validate_op_options!(opts))
138138
end
139139

140+
@doc """
141+
Works as `get!/2`, but returns all data about cache file: path, expiration, etc.
142+
143+
Useful when it's required to set HTTP's Cache-Control header
144+
or work with cache file manually (e.g. pass its path to external program)
145+
"""
146+
def get_record!(id, opts \\ []) do
147+
do_get_record!(validate_id!(id), validate_op_options!(opts))
148+
end
149+
140150
def exists?(id, opts) do
141151
id
142152
|> validate_id!()
@@ -186,9 +196,20 @@ defmodule FileCache do
186196
end
187197

188198
defp do_get!(id, opts) do
189-
case Perm.find(id, opts[:cache], opts) do
190-
nil -> nil
191-
path -> File.stream!(path)
199+
with result when is_map(result) <- Perm.find(id, opts[:cache], opts) do
200+
File.stream!(result.path)
201+
end
202+
end
203+
204+
def do_get_record!(id, opts) do
205+
with result when is_map(result) <- Perm.find(id, opts[:cache], opts) do
206+
%FileCache.Record{
207+
id: result.id,
208+
path: result.path,
209+
expires_at: result.expires_at,
210+
ttl: result.expires_at - Utils.system_time(),
211+
stream: File.stream!(result.path)
212+
}
192213
end
193214
end
194215

lib/file_cache/perm.ex

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ defmodule FileCache.Perm do
2525
#
2626
# So for the time being, we are finding (and cleaning) *all* files with the suffix of `id`
2727

28-
result = find_all(id, cache_name, opts)[id]
29-
result && result[:path]
28+
find_all(id, cache_name, opts)[id]
3029
end
3130

3231
def find_all(cache_name), do: find_all(cache_name, [])
@@ -40,9 +39,7 @@ defmodule FileCache.Perm do
4039
now = Utils.system_time()
4140
{sync_clean?, _opts} = Keyword.pop(opts, :sync_clean, false)
4241

43-
cache_name
44-
|> wildcard(id)
45-
|> Enum.reduce(%{}, fn path, acc ->
42+
reduce_all(id, cache_name, %{}, fn path, acc ->
4643
with {:ok, this} <- parse_filepath(path, cache_name) do
4744
exp = this.expires_at
4845
last = Map.get(acc, this.id)
@@ -67,6 +64,12 @@ defmodule FileCache.Perm do
6764
end)
6865
end
6966

67+
def reduce_all(id, cache_name, acc, fun) do
68+
cache_name
69+
|> wildcard(id)
70+
|> Enum.reduce(acc, fun)
71+
end
72+
7073
def delete(id, cache_name, _opts) do
7174
cache_name
7275
|> wildcard(id)

lib/file_cache/record.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
defmodule FileCache.Record do
2+
@moduledoc """
3+
Structure for FileCache record with cache id, content file's path, expiration timestamp, time-to-live and file stream,
4+
as returned by common FileCache operations
5+
"""
6+
7+
defstruct [:id, :path, :expires_at, :ttl, :stream]
8+
end

test/file_cache_test.exs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,40 @@ defmodule FileCacheTest do
117117
end
118118
end
119119

120+
describe "get_record!" do
121+
setup do
122+
setup_cache(ttl: 60_000)
123+
end
124+
125+
test "returns nil for missing key", c do
126+
assert nil == FileCache.get_record!("not_exist", opts(c))
127+
end
128+
129+
test "get complete record about cache file", c do
130+
data = 1..10
131+
132+
start_timestamp = FileCache.Utils.system_time()
133+
assert binary(data) == read!(FileCache.put!(binary(data), @key, opts(c)))
134+
135+
assert %FileCache.Record{
136+
id: id,
137+
path: path,
138+
stream: stream,
139+
expires_at: expires_at,
140+
ttl: ttl
141+
} = FileCache.get_record!(@key, opts(c))
142+
143+
assert @key == id
144+
assert binary(data) == read!(stream)
145+
assert binary(data) == read!(File.stream!(path))
146+
147+
assert 59_000 <= ttl and ttl < 61_000
148+
149+
test_ttl = expires_at - start_timestamp
150+
assert 59_000 <= test_ttl and test_ttl < 61_000
151+
end
152+
end
153+
120154
describe "execute!" do
121155
setup do
122156
setup_cache()

0 commit comments

Comments
 (0)