json-streamer 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 228fd4a492c65890dea98aeb1b2d8f5e0346704a
4
- data.tar.gz: ea930d766ae7c7c5f8ef3d1ea15cc4f0af23d012
3
+ metadata.gz: 4f04ab89c1174d12704fb5bf27ed2c7663ab6c95
4
+ data.tar.gz: 95e508c4081e086a58a579d1147ac63d88f86d81
5
5
  SHA512:
6
- metadata.gz: 558ba471b5a0ad18eccca5250bcd15c7e2e48d58040ac83cd88f032db9c25a2b18b55f458507d9b762d6f129b87fd57daff7a67e5e91e55c2a27b97ade324e18
7
- data.tar.gz: 6b286e416488996dec24d18ef3976d99f41585ee62ac23172c39de21834eb2ed06fe3b977dd0f0e92d9de0e42d28670bebaee7423a359c34f1bf0c9c67c6ab24
6
+ metadata.gz: 612d180722eb1b7c07b4855dc24a5a9971bb6bb8dd20b66743aa06bcf98eee39845c8e313b3f7952c582cd6915571d11a0534ce71a2cf70a1e4ab1d8c54ff1f8
7
+ data.tar.gz: 48feddeccbadaa95784fe23ebee4bcbbe87dbf27b440ad7f9b10cbac230665be29e005671f304e4d7727e2e06fef6620bb47c5e5601e0af220f3f944de928f34
data/.gitignore CHANGED
@@ -1,10 +1,10 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- .idea/*
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .idea/*
@@ -0,0 +1,3 @@
1
+ [submodule "ruby-devenv"]
2
+ path = ruby-devenv
3
+ url = https://github.com/thisismydesign/ruby-devenv
@@ -1,49 +1,49 @@
1
- # Contributor Code of Conduct
2
-
3
- As contributors and maintainers of this project, and in the interest of
4
- fostering an open and welcoming community, we pledge to respect all people who
5
- contribute through reporting issues, posting feature requests, updating
6
- documentation, submitting pull requests or patches, and other activities.
7
-
8
- We are committed to making participation in this project a harassment-free
9
- experience for everyone, regardless of level of experience, gender, gender
10
- identity and expression, sexual orientation, disability, personal appearance,
11
- body size, race, ethnicity, age, religion, or nationality.
12
-
13
- Examples of unacceptable behavior by participants include:
14
-
15
- * The use of sexualized language or imagery
16
- * Personal attacks
17
- * Trolling or insulting/derogatory comments
18
- * Public or private harassment
19
- * Publishing other's private information, such as physical or electronic
20
- addresses, without explicit permission
21
- * Other unethical or unprofessional conduct
22
-
23
- Project maintainers have the right and responsibility to remove, edit, or
24
- reject comments, commits, code, wiki edits, issues, and other contributions
25
- that are not aligned to this Code of Conduct, or to ban temporarily or
26
- permanently any contributor for other behaviors that they deem inappropriate,
27
- threatening, offensive, or harmful.
28
-
29
- By adopting this Code of Conduct, project maintainers commit themselves to
30
- fairly and consistently applying these principles to every aspect of managing
31
- this project. Project maintainers who do not follow or enforce the Code of
32
- Conduct may be permanently removed from the project team.
33
-
34
- This code of conduct applies both within project spaces and in public spaces
35
- when an individual is representing the project or its community.
36
-
37
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
- reported by contacting a project maintainer at csapagyi@users.noreply.github.com. All
39
- complaints will be reviewed and investigated and will result in a response that
40
- is deemed necessary and appropriate to the circumstances. Maintainers are
41
- obligated to maintain confidentiality with regard to the reporter of an
42
- incident.
43
-
44
- This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
- version 1.3.0, available at
46
- [http://contributor-covenant.org/version/1/3/0/][version]
47
-
48
- [homepage]: http://contributor-covenant.org
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at csapagyi@users.noreply.github.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
49
  [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in json-streamer.gemspec
4
- gemspec
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in json-streamer.gemspec
4
+ gemspec
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2016 Csaba Apagyi
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Csaba Apagyi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,126 +1,151 @@
1
- # Json::Streamer
2
-
3
- Utility to support JSON streaming allowing you to get data based on various criteria (key, nesting level, etc).
4
-
5
- This gem will basically spare you the need to define you own callbacks when parsing JSON stream.
6
- Streaming is useful for
7
- - big files that not fit in the memory (or you'd rather avoid the risk)
8
- - files read in chunks (e.g. arriving over network)
9
- - cases where you expect some issue with the file (e.g. losing connection to source, invalid data at some point) but would like to get as much data as possible anyway
10
-
11
- Performance:
12
-
13
- The gem uses JSON::Stream's events in the background. It was chosen because it's a pure Ruby parser.
14
- A similar implementation can be done using the ~10 times faster Yajl::FFI gem that is dependent on the native YAJL library.
15
- I did not measure the performance of my implementation on top of these libraries.
16
-
17
- I do not recommend this or any of the gems mentioned above if you don't need streaming.
18
-
19
- ## Installation
20
-
21
- Add this line to your application's Gemfile:
22
-
23
- ```ruby
24
- gem 'json-streamer'
25
- ```
26
-
27
- And then execute:
28
-
29
- $ bundle
30
-
31
- Or install it yourself as:
32
-
33
- $ gem install json-streamer
34
-
35
- ## Usage
36
-
37
- ```ruby
38
- require 'json/streamer'
39
-
40
- # Get a JsonStreamer object that will parse file_stream by chunks of 500
41
- # Default chunk size in 1000
42
- streamer = Json::Streamer::JsonStreamer.new(file_stream, 500)
43
- ```
44
-
45
- ```ruby
46
- # Get objects based on nesting level
47
- # Level zero will give you the full JSON, first level will give you data within full JSON object, etc.
48
- streamer.get(nesting_level:1).each do |object|
49
- p object
50
- end
51
- ```
52
-
53
- ```json
54
- {
55
- "object1": {},
56
- "object2": {}
57
- }
58
-
59
- =>
60
-
61
- {}
62
- {}
63
- ```
64
-
65
- ```ruby
66
- # Get data based on key
67
- streamer.get(key:'key').each do |object|
68
- p object
69
- end
70
- ```
71
-
72
- ```json
73
- {
74
- "obj1" : {
75
- "key" : "value"
76
- },
77
- "key" : "value",
78
- "obj2" : {
79
- "key" : {
80
- "key" : "value"
81
- }
82
- }
83
- }
84
-
85
- =>
86
-
87
- "value"
88
- "value"
89
- "value"
90
- {"key" : "value"}
91
- ```
92
-
93
- ```ruby
94
- # You can also skip values if you'd only like to get objects and arrays
95
- streamer.get(nesting_level:1, yield_values:false).each do |object|
96
- p object
97
- end
98
- ```
99
-
100
- ```json
101
- {
102
- "obj1" : {}
103
- "key" : "value"
104
- }
105
-
106
- =>
107
-
108
- {}
109
- ```
110
-
111
- Check the unit tests for more examples.
112
-
113
- ## Development
114
-
115
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
116
-
117
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
118
-
119
- ## Contributing
120
-
121
- Bug reports and pull requests are welcome on GitHub at https://github.com/csapagyi/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.
122
-
123
-
124
- ## License
125
-
126
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
1
+ # Json::Streamer
2
+
3
+ Ruby utility that supports JSON streaming allowing you to get data based on various criteria (key, nesting level, etc).
4
+
5
+ *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)):*
6
+
7
+ 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.).
8
+
9
+
10
+ *If you're new to this:*
11
+
12
+ Streaming is useful for
13
+ - big files that do not fit in the memory (or you'd rather avoid the risk)
14
+ - files read in chunks (e.g. arriving over network)
15
+ - cases where you expect some issue with the file (e.g. losing connection to source, invalid data at some point) but would like to get as much data as possible anyway
16
+
17
+ This gem is aimed at making streaming as easy and convenient as possible.
18
+
19
+ *Performance:*
20
+
21
+ The gem uses JSON::Stream's events in the background. It was chosen because it's a pure Ruby parser.
22
+ A similar implementation can be done using the ~10 times faster Yajl::FFI gem that is dependent on the native YAJL library.
23
+ I did not measure the performance of my implementation on top of these libraries.
24
+
25
+ ## Installation
26
+
27
+ Add this line to your application's Gemfile:
28
+
29
+ ```ruby
30
+ gem 'json-streamer'
31
+ ```
32
+
33
+ And then execute:
34
+
35
+ $ bundle
36
+
37
+ Or install it yourself as:
38
+
39
+ $ gem install json-streamer
40
+
41
+ ## Usage
42
+
43
+ ```ruby
44
+ require 'json/streamer'
45
+
46
+ file_stream = File.open('data.json', 'r')
47
+
48
+ # Get a JsonStreamer object that will parse file_stream by chunks of 500
49
+ # Default chunk size in 1000
50
+ streamer = Json::Streamer::JsonStreamer.new(file_stream, 500)
51
+ ```
52
+
53
+ #### Get objects based on nesting level
54
+
55
+ ```ruby
56
+ # Level zero will give you the full JSON, first level will give you data within full JSON object, etc.
57
+ streamer.get(nesting_level:1) do |object|
58
+ p object
59
+ end
60
+ ```
61
+
62
+ Input:
63
+ ```json
64
+ {
65
+ "object1": "first_level_value",
66
+ "object2": {}
67
+ }
68
+ ```
69
+
70
+ Output:
71
+ ```json
72
+ "first_level_value"
73
+ {}
74
+ ```
75
+
76
+ #### Get data based on key
77
+
78
+ ```ruby
79
+ streamer.get(key:'desired_key') do |object|
80
+ p object
81
+ end
82
+ ```
83
+
84
+ Input:
85
+ ```json
86
+ {
87
+ "obj1" : {
88
+ "desired_key" : "value1"
89
+ },
90
+ "desired_key" : "value2",
91
+ "obj2" : {
92
+ "desired_key" : {
93
+ "desired_key" : "value3"
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ Output:
100
+ ```json
101
+ "value1"
102
+ "value2"
103
+ "value3"
104
+ {"desired_key" : "value3"}
105
+ ```
106
+
107
+ #### Skip values if you'd only like to get objects and arrays
108
+
109
+ ```ruby
110
+ streamer.get(nesting_level:1, yield_values:false) do |object|
111
+ p object
112
+ end
113
+ ```
114
+
115
+ Input:
116
+ ```json
117
+ {
118
+ "obj1" : {},
119
+ "key" : "value"
120
+ }
121
+ ```
122
+
123
+ Output:
124
+ ```json
125
+ {}
126
+ ```
127
+
128
+ Check the unit tests for more examples ([spec/streamer_spec.rb](spec/streamer_spec.rb)).
129
+
130
+ ## Feedback
131
+
132
+ Any feedback is much appreciated.
133
+
134
+ I can only tailor this project to fit use-cases I know about - which are usually my own ones. If you find that this might be the right direction to solve your problem too but you find that it's suboptimal or lacks features don't hesitate to contact me.
135
+
136
+ Please let me know if you make use of this project so that I can prioritize further efforts.
137
+
138
+ ## Development
139
+
140
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
141
+
142
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
143
+
144
+ ## Contributing
145
+
146
+ 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.
147
+
148
+
149
+ ## License
150
+
151
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,2 +1,2 @@
1
- require "bundler/gem_tasks"
2
- task :default => :spec
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -1,14 +1,14 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "json/streamer"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "json/streamer"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup CHANGED
@@ -1,8 +1,8 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -1,26 +1,30 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'json/streamer/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "json-streamer"
8
- spec.version = Json::Streamer::VERSION
9
- spec.authors = ["Csaba Apagyi"]
10
- spec.email = ["csapagyi@users.noreply.github.com"]
11
-
12
- spec.summary = %q{Utility to support JSON streaming allowing you to get data based on various criteria (key, nesting level, etc)}
13
- spec.homepage = "https://github.com/csapagyi/json-streamer"
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
- spec.bindir = "exe"
18
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_development_dependency "bundler", "~> 1.12.a"
22
- spec.add_development_dependency "rake", "~> 10.0"
23
- spec.add_development_dependency "json-stream"
24
- spec.add_development_dependency "rspec"
25
- spec.add_development_dependency "ndhash"
26
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'json/streamer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "json-streamer"
8
+ spec.version = Json::Streamer::VERSION
9
+ spec.authors = ["thisismydesign"]
10
+ spec.email = ["thisismydesign@users.noreply.github.com"]
11
+
12
+ spec.summary = %q{Utility to support JSON streaming allowing you to get data based on various criteria (key, nesting level, etc)}
13
+ spec.homepage = "https://github.com/thisismydesign/json-streamer"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ # Because of `require_relative`
22
+ spec.required_ruby_version = '>= 1.9.2'
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.14"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "ndhash"
28
+
29
+ spec.add_dependency "json-stream"
30
+ end
@@ -1,111 +1,7 @@
1
- require "json/streamer/version"
2
- require "json/stream"
3
-
4
- module Json
5
- module Streamer
6
- class JsonStreamer
7
-
8
- attr_reader :aggregator
9
-
10
- def initialize(file_io, chunk_size = 1000)
11
- @parser = JSON::Stream::Parser.new
12
-
13
- @file_io = file_io
14
- @chunk_size = chunk_size
15
-
16
- @current_nesting_level = -1
17
- @current_key = nil
18
- @aggregator = {}
19
- @temp_aggregator_keys = {}
20
-
21
- @parser.start_object {start_object}
22
- @parser.start_array {start_array}
23
- @parser.key {|k| key(k)}
24
-
25
- end
26
-
27
- # Callbacks containing yield has be defined in the method called via block
28
- def get(nesting_level:-1, key:nil, yield_values:true)
29
- @yield_nesting_level = nesting_level
30
- @wanted_key = key
31
- @yield_values = yield_values
32
-
33
- @parser.value do |v|
34
- if @aggregator[@current_nesting_level].kind_of? Array
35
- @aggregator[@current_nesting_level] << v
36
- else
37
- @aggregator[@current_nesting_level][@current_key] = v
38
- if @yield_values and yield_value?
39
- yield v
40
- end
41
- end
42
- end
43
-
44
- @parser.end_object do
45
- if yield_object?
46
- yield @aggregator[@current_nesting_level].clone
47
- # TODO probably can be faster than reject!{true}
48
- @aggregator[@current_nesting_level].reject!{true}
49
- else
50
- merge_up
51
- end
52
-
53
- @current_nesting_level -= 1
54
- end
55
-
56
- @parser.end_array do
57
- if yield_object?
58
- yield @aggregator[@current_nesting_level].clone
59
- # TODO probably can be faster than reject!{true}
60
- @aggregator[@current_nesting_level].reject!{true}
61
- else
62
- merge_up
63
- end
64
-
65
- @current_nesting_level -= 1
66
- end
67
-
68
- @file_io.each(@chunk_size) do |chunk|
69
- @parser << chunk
70
- end
71
- end
72
-
73
- def yield_object?
74
- @current_nesting_level.eql? @yield_nesting_level or (not @wanted_key.nil? and @wanted_key == @temp_aggregator_keys[@current_nesting_level-1])
75
- end
76
-
77
- def yield_value?
78
- (@current_nesting_level + 1).eql? @yield_nesting_level or @wanted_key == @current_key
79
- end
80
-
81
- def start_object
82
- @temp_aggregator_keys[@current_nesting_level] = @current_key
83
- @current_nesting_level += 1
84
- @aggregator[@current_nesting_level] = {}
85
- end
86
-
87
- def start_array
88
- @temp_aggregator_keys[@current_nesting_level] = @current_key
89
- @current_nesting_level += 1
90
- @aggregator[@current_nesting_level] = []
91
- end
92
-
93
- def key(k)
94
- @current_key = k
95
- end
96
-
97
- def merge_up
98
- return if @current_nesting_level == 0
99
- previous_nesting_level = @current_nesting_level - 1
100
- if @aggregator[previous_nesting_level].kind_of? Array
101
- @aggregator[previous_nesting_level] << @aggregator[@current_nesting_level]
102
- else
103
- @aggregator[previous_nesting_level][@temp_aggregator_keys[previous_nesting_level]] = @aggregator[@current_nesting_level]
104
- end
105
-
106
- @aggregator.delete(@current_nesting_level)
107
- @aggregator
108
- end
109
- end
110
- end
111
- end
1
+ require_relative "streamer/json_streamer"
2
+
3
+ module Json
4
+ module Streamer
5
+
6
+ end
7
+ end
@@ -0,0 +1,107 @@
1
+ require "json/stream"
2
+
3
+ module Json
4
+ module Streamer
5
+ class JsonStreamer
6
+
7
+ attr_reader :aggregator
8
+
9
+ def initialize(file_io, chunk_size = 1000)
10
+ @parser = JSON::Stream::Parser.new
11
+
12
+ @file_io = file_io
13
+ @chunk_size = chunk_size
14
+
15
+ @current_nesting_level = -1
16
+ @current_key = nil
17
+ @aggregator = {}
18
+ @temp_aggregator_keys = {}
19
+
20
+ @parser.start_object {start_object}
21
+ @parser.start_array {start_array}
22
+ @parser.key {|k| key(k)}
23
+
24
+ end
25
+
26
+ # Callbacks containing `yield` have to be defined in the method called via block otherwise yield won't work
27
+ def get(nesting_level:-1, key:nil, yield_values:true)
28
+ yield_nesting_level = nesting_level
29
+ wanted_key = key
30
+
31
+ @parser.value do |v|
32
+ if @aggregator[@current_nesting_level].kind_of? Array
33
+ @aggregator[@current_nesting_level] << v
34
+ else
35
+ @aggregator[@current_nesting_level][@current_key] = v
36
+ if yield_values and yield_value?(yield_nesting_level, wanted_key)
37
+ yield v
38
+ end
39
+ end
40
+ end
41
+
42
+ @parser.end_object do
43
+ if yield_object?(yield_nesting_level, wanted_key)
44
+ yield @aggregator[@current_nesting_level].clone
45
+ @aggregator[@current_nesting_level] = {}
46
+ else
47
+ merge_up
48
+ end
49
+
50
+ @current_nesting_level -= 1
51
+ end
52
+
53
+ @parser.end_array do
54
+ if yield_object?(yield_nesting_level, wanted_key)
55
+ yield @aggregator[@current_nesting_level].clone
56
+ @aggregator[@current_nesting_level] = []
57
+ else
58
+ merge_up
59
+ end
60
+
61
+ @current_nesting_level -= 1
62
+ end
63
+
64
+ @file_io.each(@chunk_size) do |chunk|
65
+ @parser << chunk
66
+ end
67
+ end
68
+
69
+ def yield_object?(yield_nesting_level, wanted_key)
70
+ @current_nesting_level.eql? yield_nesting_level or (not wanted_key.nil? and wanted_key == @temp_aggregator_keys[@current_nesting_level-1])
71
+ end
72
+
73
+ def yield_value?(yield_nesting_level, wanted_key)
74
+ (@current_nesting_level + 1).eql? yield_nesting_level or wanted_key == @current_key
75
+ end
76
+
77
+ def start_object
78
+ @temp_aggregator_keys[@current_nesting_level] = @current_key
79
+ @current_nesting_level += 1
80
+ @aggregator[@current_nesting_level] = {}
81
+ end
82
+
83
+ def start_array
84
+ @temp_aggregator_keys[@current_nesting_level] = @current_key
85
+ @current_nesting_level += 1
86
+ @aggregator[@current_nesting_level] = []
87
+ end
88
+
89
+ def key(k)
90
+ @current_key = k
91
+ end
92
+
93
+ def merge_up
94
+ return if @current_nesting_level == 0
95
+ previous_nesting_level = @current_nesting_level - 1
96
+ if @aggregator[previous_nesting_level].kind_of? Array
97
+ @aggregator[previous_nesting_level] << @aggregator[@current_nesting_level]
98
+ else
99
+ @aggregator[previous_nesting_level][@temp_aggregator_keys[previous_nesting_level]] = @aggregator[@current_nesting_level]
100
+ end
101
+
102
+ @aggregator.delete(@current_nesting_level)
103
+ @aggregator
104
+ end
105
+ end
106
+ end
107
+ end
@@ -1,5 +1,5 @@
1
- module Json
2
- module Streamer
3
- VERSION = "0.5.0"
4
- end
5
- end
1
+ module Json
2
+ module Streamer
3
+ VERSION = "0.6.0"
4
+ end
5
+ 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: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
- - Csaba Apagyi
7
+ - thisismydesign
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-05-29 00:00:00.000000000 Z
11
+ date: 2017-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.12.a
19
+ version: '1.14'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.12.a
26
+ version: '1.14'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -39,21 +39,21 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: json-stream
42
+ name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rspec
56
+ name: ndhash
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,13 +67,13 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: ndhash
70
+ name: json-stream
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- type: :development
76
+ type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
@@ -82,12 +82,13 @@ dependencies:
82
82
  version: '0'
83
83
  description:
84
84
  email:
85
- - csapagyi@users.noreply.github.com
85
+ - thisismydesign@users.noreply.github.com
86
86
  executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - ".gitignore"
91
+ - ".gitmodules"
91
92
  - CODE_OF_CONDUCT.md
92
93
  - Gemfile
93
94
  - LICENSE.txt
@@ -97,8 +98,9 @@ files:
97
98
  - bin/setup
98
99
  - json-streamer.gemspec
99
100
  - lib/json/streamer.rb
101
+ - lib/json/streamer/json_streamer.rb
100
102
  - lib/json/streamer/version.rb
101
- homepage: https://github.com/csapagyi/json-streamer
103
+ homepage: https://github.com/thisismydesign/json-streamer
102
104
  licenses:
103
105
  - MIT
104
106
  metadata: {}
@@ -110,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
112
  requirements:
111
113
  - - ">="
112
114
  - !ruby/object:Gem::Version
113
- version: '0'
115
+ version: 1.9.2
114
116
  required_rubygems_version: !ruby/object:Gem::Requirement
115
117
  requirements:
116
118
  - - ">="
@@ -118,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
120
  version: '0'
119
121
  requirements: []
120
122
  rubyforge_project:
121
- rubygems_version: 2.5.1
123
+ rubygems_version: 2.5.2
122
124
  signing_key:
123
125
  specification_version: 4
124
126
  summary: Utility to support JSON streaming allowing you to get data based on various