batch-loader 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -2
- data/README.md +21 -0
- data/lib/batch_loader.rb +14 -4
- data/lib/batch_loader/executor_proxy.rb +8 -3
- data/lib/batch_loader/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 124dbf8b2fa20f0e0fd6bca686449f48c3dd3625
|
4
|
+
data.tar.gz: d10abd20d3f55f64871673b5410c8d92539abaa5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e97a8dcbb31e6310dc2b40df35143f6bdac4a1153b1ea9de175f07b36e8df0da7890e1c445f91c782e3ac1804ee0129107329685e0aac50dcafadbe17278c3a
|
7
|
+
data.tar.gz: 93188a2738ac3f57735e0643003818b19eb4875c2b748fbbf0e19751c837a8ba32247b84fa84533bb2bbe84515eb35fc28f31929813871c6eb21b9fc08a1d4b8
|
data/CHANGELOG.md
CHANGED
@@ -8,11 +8,16 @@ one of the following labels: `Added`, `Changed`, `Deprecated`,
|
|
8
8
|
to manage the versions of this gem so
|
9
9
|
that you can set version constraints properly.
|
10
10
|
|
11
|
-
#### [Unreleased](https://github.com/exAspArk/batch-loader/compare/v1.0
|
11
|
+
#### [Unreleased](https://github.com/exAspArk/batch-loader/compare/v1.1.0...HEAD)
|
12
12
|
|
13
13
|
* WIP
|
14
14
|
|
15
|
-
#### [
|
15
|
+
#### [v1.1.0](https://github.com/exAspArk/batch-loader/compare/v1.0.4...v1.1.0)
|
16
|
+
|
17
|
+
* `Added`: `default_value` override option. [#8](https://github.com/exAspArk/batch-loader/pull/8)
|
18
|
+
* `Added`: `loader.call {}` block syntax, for memoizing repeat calls to the same item. [#8](https://github.com/exAspArk/batch-loader/pull/8)
|
19
|
+
|
20
|
+
#### [v1.0.4](https://github.com/exAspArk/batch-loader/compare/v1.0.3...v1.0.4)
|
16
21
|
|
17
22
|
* `Fixed`: Fix arity bug in `respond_to?` [#3](https://github.com/exAspArk/batch-loader/pull/3)
|
18
23
|
|
data/README.md
CHANGED
@@ -17,6 +17,7 @@ This gem provides a generic lazy batching mechanism to avoid N+1 DB queries, HTT
|
|
17
17
|
* [How it works](#how-it-works)
|
18
18
|
* [RESTful API example](#restful-api-example)
|
19
19
|
* [GraphQL example](#graphql-example)
|
20
|
+
* [Loading multiple items](#loading-multiple-items)
|
20
21
|
* [Caching](#caching)
|
21
22
|
* [Installation](#installation)
|
22
23
|
* [Implementation details](#implementation-details)
|
@@ -279,6 +280,26 @@ end
|
|
279
280
|
|
280
281
|
That's it.
|
281
282
|
|
283
|
+
### Loading multiple items
|
284
|
+
|
285
|
+
For batches where there is no item in response to a call, we normally return `nil`. However, you can use `:default_value` to return something else instead:
|
286
|
+
|
287
|
+
```ruby
|
288
|
+
BatchLoader.for(post.user_id).batch(default_value: NullUser.new) do |user_ids, loader|
|
289
|
+
User.where(id: user_ids).each { |user| loader.call(user.id, user) }
|
290
|
+
end
|
291
|
+
```
|
292
|
+
|
293
|
+
For batches where the value is some kind of collection, such as an Array or Hash, `loader` also supports being called with a block, which yields the _current_ value, and returns the _next_ value. This is extremely useful for 1:Many relationships:
|
294
|
+
|
295
|
+
```ruby
|
296
|
+
BatchLoader.for(user.id).batch(default_value: []) do |comment_ids, loader|
|
297
|
+
Comment.where(user_id: user_ids).each do |comment|
|
298
|
+
loader.call(user.id) { |memo| memo << comment }
|
299
|
+
end
|
300
|
+
end
|
301
|
+
```
|
302
|
+
|
282
303
|
### Caching
|
283
304
|
|
284
305
|
By default `BatchLoader` caches the loaded values. You can test it by running something like:
|
data/lib/batch_loader.rb
CHANGED
@@ -22,7 +22,8 @@ class BatchLoader
|
|
22
22
|
@item = item
|
23
23
|
end
|
24
24
|
|
25
|
-
def batch(cache: true, &batch_block)
|
25
|
+
def batch(default_value: nil, cache: true, &batch_block)
|
26
|
+
@default_value = default_value
|
26
27
|
@cache = cache
|
27
28
|
@batch_block = batch_block
|
28
29
|
__executor_proxy.add(item: @item)
|
@@ -75,12 +76,21 @@ class BatchLoader
|
|
75
76
|
return if __executor_proxy.value_loaded?(item: @item)
|
76
77
|
|
77
78
|
items = __executor_proxy.list_items
|
78
|
-
loader =
|
79
|
+
loader = -> (item, value = (no_value = true; nil), &block) {
|
80
|
+
if no_value && !block
|
81
|
+
raise ArgumentError, "Please pass a value or a block"
|
82
|
+
elsif block && !no_value
|
83
|
+
raise ArgumentError, "Please pass a value or a block, not both"
|
84
|
+
end
|
85
|
+
|
86
|
+
next_value = block ? block.call(__executor_proxy.loaded_value(item: item)) : value
|
87
|
+
__executor_proxy.load(item: item, value: next_value)
|
88
|
+
}
|
79
89
|
|
80
90
|
@batch_block.call(items, loader)
|
81
91
|
items.each do |item|
|
82
92
|
next if __executor_proxy.value_loaded?(item: item)
|
83
|
-
loader.call(item,
|
93
|
+
loader.call(item, @default_value)
|
84
94
|
end
|
85
95
|
__executor_proxy.delete(items: items)
|
86
96
|
end
|
@@ -109,7 +119,7 @@ class BatchLoader
|
|
109
119
|
def __executor_proxy
|
110
120
|
@__executor_proxy ||= begin
|
111
121
|
raise NoBatchError.new("Please provide a batch block first") unless @batch_block
|
112
|
-
BatchLoader::ExecutorProxy.new(&@batch_block)
|
122
|
+
BatchLoader::ExecutorProxy.new(@default_value, &@batch_block)
|
113
123
|
end
|
114
124
|
end
|
115
125
|
|
@@ -4,9 +4,10 @@ require_relative "./executor"
|
|
4
4
|
|
5
5
|
class BatchLoader
|
6
6
|
class ExecutorProxy
|
7
|
-
attr_reader :block, :global_executor
|
7
|
+
attr_reader :default_value, :block, :global_executor
|
8
8
|
|
9
|
-
def initialize(&block)
|
9
|
+
def initialize(default_value, &block)
|
10
|
+
@default_value = default_value
|
10
11
|
@block = block
|
11
12
|
@block_hash_key = block.source_location
|
12
13
|
@global_executor = BatchLoader::Executor.ensure_current
|
@@ -29,7 +30,11 @@ class BatchLoader
|
|
29
30
|
end
|
30
31
|
|
31
32
|
def loaded_value(item:)
|
32
|
-
|
33
|
+
if value_loaded?(item: item)
|
34
|
+
loaded[item]
|
35
|
+
else
|
36
|
+
@default_value.dup
|
37
|
+
end
|
33
38
|
end
|
34
39
|
|
35
40
|
def value_loaded?(item:)
|
data/lib/batch_loader/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: batch-loader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- exAspArk
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|