json-streamer 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +4 -0
- data/README.md +95 -24
- data/json-streamer.gemspec +1 -0
- data/lib/json/streamer.rb +2 -2
- data/lib/json/streamer/json_streamer.rb +30 -7
- data/lib/json/streamer/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8a3dd5e19a0ad214f6121458dd0de84db79a45ba2f321a83eadfbb26de2f575c
|
4
|
+
data.tar.gz: 55099a1cddf21b0392eae5306b74d9e7e7fd2665d12fd5c995a972786afc2d71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87c6bbe06080168b7711c6620aa8522f6d86976db1dc826e889b1ca02b29ca467c89e054aba36063b392fb8a9052945fc60c08009853cd89ea6ec1481d23ca9a
|
7
|
+
data.tar.gz: 3335826bd0f377b72db28fbbdeb882067f84203f03fc68eb6e957bda0a19c82790ffe743117442cee49bcff4fde285675e054d4b3ff05ecb103c864c52035124
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,18 +1,27 @@
|
|
1
1
|
# Json::Streamer
|
2
2
|
|
3
|
-
#### Ruby
|
3
|
+
#### Ruby gem for getting data from JSON streams based on various criteria (key, nesting level, etc).
|
4
|
+
|
5
|
+
Status and support
|
6
|
+
|
7
|
+
- ✔ stable
|
8
|
+
- ✔ supported
|
9
|
+
- ✖ no ongoing development
|
10
|
+
|
11
|
+
<!--- Version informartion -->
|
12
|
+
*You are viewing the README of version [v2.1.0](https://github.com/thisismydesign/json-streamer/releases/tag/v2.1.0). You can find other releases [here](https://github.com/thisismydesign/json-streamer/releases).*
|
13
|
+
<!--- Version informartion end -->
|
4
14
|
|
5
15
|
| Branch | Status |
|
6
16
|
| ------ | ------ |
|
7
17
|
| Release | [![Build Status](https://travis-ci.org/thisismydesign/json-streamer.svg?branch=release)](https://travis-ci.org/thisismydesign/json-streamer) [![Coverage Status](https://coveralls.io/repos/github/thisismydesign/json-streamer/badge.svg?branch=release)](https://coveralls.io/github/thisismydesign/json-streamer?branch=release) [![Gem Version](https://badge.fury.io/rb/json-streamer.svg)](https://badge.fury.io/rb/json-streamer) [![Total Downloads](http://ruby-gem-downloads-badge.herokuapp.com/json-streamer?type=total)](https://rubygems.org/gems/json-streamer) |
|
8
18
|
| Development | [![Build Status](https://travis-ci.org/thisismydesign/json-streamer.svg?branch=master)](https://travis-ci.org/thisismydesign/json-streamer) [![Coverage Status](https://coveralls.io/repos/github/thisismydesign/json-streamer/badge.svg?branch=master)](https://coveralls.io/github/thisismydesign/json-streamer?branch=master) |
|
9
19
|
|
10
|
-
|
20
|
+
#### If you've tried JSON streaming with other Ruby libraries before (e.g. [JSON::Stream](https://github.com/dgraham/json-stream), [Yajl::FFI](https://github.com/dgraham/yajl-ffi))
|
11
21
|
|
12
22
|
This gem will basically spare you the need to define your own callbacks (i.e. implement an actual JSON parser using `start_object`, `end_object`, `key`, `value`, etc.).
|
13
23
|
|
14
|
-
|
15
|
-
*If you're new to this:*
|
24
|
+
#### If you're new to this
|
16
25
|
|
17
26
|
Streaming is useful for
|
18
27
|
- big files that do not fit in the memory (or you'd rather avoid the risk)
|
@@ -21,12 +30,16 @@ Streaming is useful for
|
|
21
30
|
|
22
31
|
This gem is aimed at making streaming as easy and convenient as possible.
|
23
32
|
|
24
|
-
|
33
|
+
#### Performance
|
34
|
+
|
35
|
+
Highly depends on the event generator. Out of the box the gem uses [JSON::Stream](https://github.com/dgraham/json-stream). It was chosen because it's a pure Ruby parser with no runtime dependencies. You can use any custom event generator, such as [Yajl::FFI](https://github.com/dgraham/yajl-ffi) which is dependent on the native YAJL library and is [~10 times faster](https://github.com/dgraham/yajl-ffi#performance). See the [Custom event generators](#custom-event-generators) chapter.
|
25
36
|
|
26
|
-
The gem uses JSON::Stream's events in the background. It was chosen because it's a pure Ruby parser.
|
27
|
-
A similar implementation can be done using the ~10 times faster Yajl::FFI gem that is dependent on the native YAJL library.
|
28
37
|
I did not measure the performance of my implementation on top of these libraries.
|
29
38
|
|
39
|
+
#### Dependencies
|
40
|
+
|
41
|
+
The gem's single runtime dependency is [JSON::Stream](https://github.com/dgraham/json-stream). It is only loaded if the default event generator is used.
|
42
|
+
|
30
43
|
## Installation
|
31
44
|
|
32
45
|
Add this line to your application's Gemfile:
|
@@ -45,18 +58,14 @@ Or install it yourself as:
|
|
45
58
|
|
46
59
|
## Usage
|
47
60
|
|
48
|
-
Check the unit tests for more examples ([spec/streamer_spec.rb](spec/json/streamer/json_streamer_spec.rb)).
|
49
|
-
|
50
|
-
One `streamer` object handles one set of conditions. For multiple conditions create multiple streamers. For more details see [this discussion](https://github.com/thisismydesign/json-streamer/issues/9).
|
51
|
-
|
52
61
|
```ruby
|
53
62
|
require 'json/streamer'
|
54
63
|
```
|
55
64
|
|
56
|
-
### v1.2 (and above) API
|
57
|
-
|
58
65
|
#### Passing IO upfront
|
59
66
|
|
67
|
+
Since [v1.2.0](https://github.com/thisismydesign/json-streamer/releases/tag/v1.2.0)
|
68
|
+
|
60
69
|
```ruby
|
61
70
|
file_stream = File.open('data.json', 'r')
|
62
71
|
chunk_size = 500 # defaults to 1000
|
@@ -181,9 +190,23 @@ def receive_data(data)
|
|
181
190
|
end
|
182
191
|
```
|
183
192
|
|
193
|
+
#### Custom event generators
|
194
|
+
|
195
|
+
Since [v2.1.0](https://github.com/thisismydesign/json-streamer/releases/tag/v2.1.0)
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
require "yajl/ffi"
|
199
|
+
|
200
|
+
Json::Streamer.parser(event_generator: Yajl::FFI::Parser.new)
|
201
|
+
```
|
202
|
+
|
203
|
+
Any parser can be used that provides the right events. The gem is tested with [Yajl::FFI](https://github.com/dgraham/yajl-ffi) and [JSON::Stream](https://github.com/dgraham/json-stream).
|
204
|
+
|
184
205
|
#### Custom yield conditions
|
185
206
|
|
186
|
-
[v2.0.0](https://github.com/thisismydesign/json-streamer/releases/tag/v2.0.0)
|
207
|
+
Since [v2.0.0](https://github.com/thisismydesign/json-streamer/releases/tag/v2.0.0)
|
208
|
+
|
209
|
+
Custom conditions provide ultimate control over what to yield.
|
187
210
|
|
188
211
|
The Conditions API exposes 3 callbacks:
|
189
212
|
- `yield_value`
|
@@ -246,7 +269,61 @@ Output:
|
|
246
269
|
{"key2"=>"value"}
|
247
270
|
```
|
248
271
|
|
249
|
-
|
272
|
+
#### Get an Enumerable when not passing a block
|
273
|
+
|
274
|
+
Since [v2.1.0](https://github.com/thisismydesign/json-streamer/releases/tag/v2.1.0)
|
275
|
+
|
276
|
+
When _not_ passed a block both `get` and `get_with_conditions` return an enumerator of the requested objects. When passed a block they return an empty enumerator. This means that **when _not_ passed a block the requested objects will accumulate in memory**.
|
277
|
+
|
278
|
+
Without block
|
279
|
+
|
280
|
+
```ruby
|
281
|
+
objects = streamer.get(nesting_level:1)
|
282
|
+
p objects
|
283
|
+
```
|
284
|
+
|
285
|
+
Input:
|
286
|
+
```json
|
287
|
+
{
|
288
|
+
"object1": "first_level_value",
|
289
|
+
"object2": {}
|
290
|
+
}
|
291
|
+
```
|
292
|
+
|
293
|
+
Output:
|
294
|
+
```ruby
|
295
|
+
["first_level_value", {}]
|
296
|
+
```
|
297
|
+
|
298
|
+
With block
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
unyielded_objects = streamer.get(nesting_level:1) { |object| do_something(object) }
|
302
|
+
p unyielded_objects
|
303
|
+
```
|
304
|
+
|
305
|
+
Input:
|
306
|
+
```json
|
307
|
+
{
|
308
|
+
"object1": "first_level_value",
|
309
|
+
"object2": {}
|
310
|
+
}
|
311
|
+
```
|
312
|
+
|
313
|
+
Output:
|
314
|
+
```ruby
|
315
|
+
[]
|
316
|
+
```
|
317
|
+
|
318
|
+
#### Other usage information
|
319
|
+
|
320
|
+
Check the unit tests for more examples ([spec/streamer_spec.rb](spec/json/streamer/json_streamer_spec.rb)).
|
321
|
+
|
322
|
+
One `streamer` object handles one set of conditions. For multiple conditions create multiple streamers. For more details see [this discussion](https://github.com/thisismydesign/json-streamer/issues/9).
|
323
|
+
|
324
|
+
#### Deprecated API
|
325
|
+
|
326
|
+
Pre [v1.2.0](https://github.com/thisismydesign/json-streamer/releases/tag/v1.2.0)
|
250
327
|
|
251
328
|
This functionality is deprecated but kept for compatibility reasons.
|
252
329
|
|
@@ -260,13 +337,11 @@ streamer = Json::Streamer::JsonStreamer.new
|
|
260
337
|
streamer.parser << data
|
261
338
|
```
|
262
339
|
|
263
|
-
##
|
264
|
-
|
265
|
-
Any feedback is much appreciated.
|
340
|
+
## Contribution and feedback
|
266
341
|
|
267
|
-
|
342
|
+
This project is built around known use-cases. If have one that isn't covered don't hesitate to open an issue and start a discussion.
|
268
343
|
|
269
|
-
|
344
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/thisismydesign/json-streamer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
270
345
|
|
271
346
|
## Conventions
|
272
347
|
|
@@ -278,10 +353,6 @@ This gem is developed using the following conventions:
|
|
278
353
|
- [RFC memo about key words used to Indicate Requirement Levels](https://tools.ietf.org/html/rfc2119)
|
279
354
|
- [Bundler improvements](https://github.com/thisismydesign/bundler-improvements)
|
280
355
|
|
281
|
-
## Contributing
|
282
|
-
|
283
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/thisismydesign/json-streamer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
284
|
-
|
285
356
|
## License
|
286
357
|
|
287
358
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/json-streamer.gemspec
CHANGED
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency "guard"
|
31
31
|
spec.add_development_dependency "guard-bundler"
|
32
32
|
spec.add_development_dependency "guard-rspec"
|
33
|
+
spec.add_development_dependency "yajl-ffi"
|
33
34
|
|
34
35
|
spec.add_dependency "json-stream"
|
35
36
|
end
|
data/lib/json/streamer.rb
CHANGED
@@ -2,8 +2,8 @@ require_relative "streamer/json_streamer"
|
|
2
2
|
|
3
3
|
module Json
|
4
4
|
module Streamer
|
5
|
-
def self.parser(file_io: nil, chunk_size: 1000)
|
6
|
-
JsonStreamer.new(file_io, chunk_size)
|
5
|
+
def self.parser(file_io: nil, chunk_size: 1000, event_generator: :default)
|
6
|
+
JsonStreamer.new(file_io, chunk_size, event_generator)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require "json/stream"
|
2
|
-
|
3
1
|
require_relative 'conditions'
|
4
2
|
require_relative 'parser'
|
5
3
|
|
@@ -9,8 +7,8 @@ module Json
|
|
9
7
|
|
10
8
|
attr_reader :parser
|
11
9
|
|
12
|
-
def initialize(file_io = nil, chunk_size = 1000)
|
13
|
-
@event_generator =
|
10
|
+
def initialize(file_io = nil, chunk_size = 1000, event_generator = :default)
|
11
|
+
@event_generator = make_event_generator(event_generator)
|
14
12
|
|
15
13
|
@file_io = file_io
|
16
14
|
@chunk_size = chunk_size
|
@@ -24,24 +22,39 @@ module Json
|
|
24
22
|
conditions = Conditions.new(yield_level: nesting_level, yield_key: key)
|
25
23
|
conditions.yield_value = ->(aggregator:, value:) { false } unless yield_values
|
26
24
|
|
27
|
-
# TODO: deprecate symbolize_keys and move to initialize
|
28
25
|
@parser = Parser.new(@event_generator, symbolize_keys: symbolize_keys)
|
26
|
+
unyielded_items = []
|
29
27
|
|
30
28
|
parser.get(conditions) do |obj|
|
31
|
-
|
29
|
+
if block_given?
|
30
|
+
yield obj
|
31
|
+
else
|
32
|
+
unyielded_items.push(obj)
|
33
|
+
end
|
34
|
+
|
35
|
+
obj
|
32
36
|
end
|
33
37
|
|
34
38
|
process_io
|
39
|
+
|
40
|
+
unyielded_items
|
35
41
|
end
|
36
42
|
|
37
43
|
def get_with_conditions(conditions, options = {})
|
38
44
|
@parser = Parser.new(@event_generator, symbolize_keys: options[:symbolize_keys])
|
45
|
+
unyielded_items = []
|
39
46
|
|
40
47
|
parser.get(conditions) do |obj|
|
41
|
-
|
48
|
+
if block_given?
|
49
|
+
yield obj
|
50
|
+
else
|
51
|
+
unyielded_items.push(obj)
|
52
|
+
end
|
42
53
|
end
|
43
54
|
|
44
55
|
process_io
|
56
|
+
|
57
|
+
unyielded_items
|
45
58
|
end
|
46
59
|
|
47
60
|
def aggregator
|
@@ -53,6 +66,16 @@ module Json
|
|
53
66
|
def process_io
|
54
67
|
@file_io.each(@chunk_size) { |chunk| parser << chunk } if @file_io
|
55
68
|
end
|
69
|
+
|
70
|
+
def make_event_generator(generator)
|
71
|
+
case generator
|
72
|
+
when :default
|
73
|
+
require 'json/stream'
|
74
|
+
JSON::Stream::Parser.new
|
75
|
+
else
|
76
|
+
generator
|
77
|
+
end
|
78
|
+
end
|
56
79
|
end
|
57
80
|
end
|
58
81
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json-streamer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thisismydesign
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: yajl-ffi
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
154
|
name: json-stream
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -197,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
211
|
version: '0'
|
198
212
|
requirements: []
|
199
213
|
rubyforge_project:
|
200
|
-
rubygems_version: 2.
|
214
|
+
rubygems_version: 2.7.7
|
201
215
|
signing_key:
|
202
216
|
specification_version: 4
|
203
217
|
summary: Utility to support JSON streaming allowing you to get data based on various
|