search_flip 4.0.0.beta5 → 4.0.0.beta9
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/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +15 -0
- data/README.md +54 -2
- data/lib/search_flip.rb +9 -3
- data/lib/search_flip/config.rb +7 -1
- data/lib/search_flip/criteria.rb +28 -7
- data/lib/search_flip/http_client.rb +30 -5
- data/lib/search_flip/index.rb +1 -1
- data/lib/search_flip/json.rb +2 -13
- data/lib/search_flip/version.rb +1 -1
- data/search_flip.gemspec +1 -0
- data/spec/search_flip/criteria_spec.rb +29 -6
- data/spec/search_flip/http_client_spec.rb +7 -3
- data/spec/search_flip/index_spec.rb +1 -1
- data/spec/search_flip/json_spec.rb +3 -3
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1850108a3752d6b01de4e2c23453220ac0cf8cd1e4dd61339faeba1c66856960
|
4
|
+
data.tar.gz: 71b704481fa26e973929c19c9c7df25685b83b65e5ef470ed032531e7fb3fec6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d57dc4c3aa5c7ffd9f287bf0ed2b097eb21671a32721fea1daad735c647f8d9d8d01e78c00e9c63d222d587be19246f8cbed85c2fbbc54b2f3a32bcc447b545
|
7
|
+
data.tar.gz: fc2b76b6f04b94a3843d3f0f8d10a131bc88ea576de7576879d9f6a5d490b2cb0e84b8ff8fee87107b1cf5f7c4a3c8ff84ade40bcadbdb4811bbf0f05088b69c
|
data/.github/workflows/test.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -11,6 +11,21 @@
|
|
11
11
|
* Added `SearchFlip::Connection#get_cluster_settings` and
|
12
12
|
`#update_cluster_settings`
|
13
13
|
|
14
|
+
## v3.5.0
|
15
|
+
|
16
|
+
* Add `SearchFlip::Criteria#http_timeout` to allow specifying timeouts on
|
17
|
+
a query level
|
18
|
+
|
19
|
+
## v3.4.0
|
20
|
+
|
21
|
+
* Expose `Http#timeout` via `SearchFlip::HTTPClient`
|
22
|
+
|
23
|
+
## v3.3.0
|
24
|
+
|
25
|
+
* Update httprb
|
26
|
+
* Changed oj default options
|
27
|
+
* Allow to set oj json options
|
28
|
+
|
14
29
|
## v3.2.1
|
15
30
|
|
16
31
|
* Fix `refresh` having a empty body breaking in elasticsearch 7.11
|
data/README.md
CHANGED
@@ -51,7 +51,7 @@ CommentIndex.search("hello world").where(available: true).sort(id: "desc").aggre
|
|
51
51
|
|
52
52
|
```
|
53
53
|
|
54
|
-
Finally, SearchFlip comes with a minimal set of dependencies
|
54
|
+
Finally, SearchFlip comes with a minimal set of dependencies.
|
55
55
|
|
56
56
|
## Reference Docs
|
57
57
|
|
@@ -698,6 +698,14 @@ Specify a timeout to limit query processing time:
|
|
698
698
|
CommentIndex.timeout("3s").execute
|
699
699
|
```
|
700
700
|
|
701
|
+
* `http_timeout`
|
702
|
+
|
703
|
+
Specify a http timeout for the request which will be send to Elasticsearch:
|
704
|
+
|
705
|
+
```ruby
|
706
|
+
CommentIndex.http_timeout(3).execute
|
707
|
+
```
|
708
|
+
|
701
709
|
* `terminate_after`
|
702
710
|
|
703
711
|
Activate early query termination to stop query processing after the specified
|
@@ -756,7 +764,7 @@ end
|
|
756
764
|
This allows to use different clusters per index e.g. when migrating indices to
|
757
765
|
new versions of Elasticsearch.
|
758
766
|
|
759
|
-
You can specify basic auth, additional headers, etc via:
|
767
|
+
You can specify basic auth, additional headers, request timeouts, etc via:
|
760
768
|
|
761
769
|
```ruby
|
762
770
|
http_client = SearchFlip::HTTPClient.new
|
@@ -773,6 +781,9 @@ http_client = http_client.via("proxy.host", 8080)
|
|
773
781
|
# Custom headers
|
774
782
|
http_client = http_client.headers(key: "value")
|
775
783
|
|
784
|
+
# Timeouts
|
785
|
+
http_client = http_client.timeout(20)
|
786
|
+
|
776
787
|
SearchFlip::Connection.new(base_url: "...", http_client: http_client)
|
777
788
|
```
|
778
789
|
|
@@ -882,6 +893,47 @@ Thus, if your ORM supports `.find_each`, `#id` and `#where` you are already
|
|
882
893
|
good to go. Otherwise, simply add your custom implementation of those methods
|
883
894
|
that work with whatever ORM you use.
|
884
895
|
|
896
|
+
## JSON
|
897
|
+
|
898
|
+
SearchFlip is using the [Oj gem](https://github.com/ohler55/oj) to generate
|
899
|
+
JSON. More concretely, SearchFlip is using:
|
900
|
+
|
901
|
+
```ruby
|
902
|
+
Oj.dump({ key: "value" }, mode: :custom, use_to_json: true, time_format: :xmlschema, bigdecimal_as_decimal: false)
|
903
|
+
```
|
904
|
+
|
905
|
+
The `use_to_json` option is used for maximum compatibility, most importantly
|
906
|
+
when using rails `ActiveSupport::TimeWithZone` timestamps, which `oj` can not
|
907
|
+
serialize natively. However, `use_to_json` adds performance overhead. You can
|
908
|
+
change the json options via:
|
909
|
+
|
910
|
+
```ruby
|
911
|
+
SearchFlip::Config[:json_options] = {
|
912
|
+
mode: :custom,
|
913
|
+
use_to_json: false,
|
914
|
+
time_format: :xmlschema,
|
915
|
+
bigdecimal_as_decimal: false
|
916
|
+
}
|
917
|
+
```
|
918
|
+
|
919
|
+
However, you then have to convert timestamps manually for indexation via e.g.:
|
920
|
+
|
921
|
+
```ruby
|
922
|
+
class MyIndex
|
923
|
+
# ...
|
924
|
+
|
925
|
+
def self.serialize(model)
|
926
|
+
{
|
927
|
+
# ...
|
928
|
+
|
929
|
+
created_at: model.created_at.to_time
|
930
|
+
}
|
931
|
+
end
|
932
|
+
end
|
933
|
+
```
|
934
|
+
|
935
|
+
Please check out the oj docs for more details.
|
936
|
+
|
885
937
|
## Feature Support
|
886
938
|
|
887
939
|
* for Elasticsearch 2.x, the delete-by-query plugin is required to delete
|
data/lib/search_flip.rb
CHANGED
@@ -2,6 +2,7 @@ require "ruby2_keywords"
|
|
2
2
|
require "forwardable"
|
3
3
|
require "http"
|
4
4
|
require "thread"
|
5
|
+
require "json"
|
5
6
|
require "oj"
|
6
7
|
require "set"
|
7
8
|
|
@@ -31,10 +32,15 @@ require "search_flip/index"
|
|
31
32
|
require "search_flip/model"
|
32
33
|
|
33
34
|
module SearchFlip
|
34
|
-
class
|
35
|
-
class ConnectionError < StandardError; end
|
35
|
+
class Error < StandardError; end
|
36
36
|
|
37
|
-
class
|
37
|
+
class NotSupportedError < Error; end
|
38
|
+
|
39
|
+
class HttpError < Error; end
|
40
|
+
class ConnectionError < HttpError; end
|
41
|
+
class TimeoutError < HttpError; end
|
42
|
+
|
43
|
+
class ResponseError < Error
|
38
44
|
attr_reader :code, :body
|
39
45
|
|
40
46
|
def initialize(code:, body:)
|
data/lib/search_flip/config.rb
CHANGED
@@ -5,6 +5,12 @@ module SearchFlip
|
|
5
5
|
bulk_limit: 1_000,
|
6
6
|
bulk_max_mb: 100,
|
7
7
|
auto_refresh: false,
|
8
|
-
instrumenter: NullInstrumenter.new
|
8
|
+
instrumenter: NullInstrumenter.new,
|
9
|
+
json_options: {
|
10
|
+
mode: :custom,
|
11
|
+
use_to_json: true,
|
12
|
+
time_format: :xmlschema,
|
13
|
+
bigdecimal_as_decimal: false
|
14
|
+
}
|
9
15
|
}
|
10
16
|
end
|
data/lib/search_flip/criteria.rb
CHANGED
@@ -26,7 +26,8 @@ module SearchFlip
|
|
26
26
|
|
27
27
|
attr_accessor :target, :profile_value, :source_value, :suggest_values, :includes_values,
|
28
28
|
:eager_load_values, :preload_values, :failsafe_value, :scroll_args, :terminate_after_value,
|
29
|
-
:timeout_value, :preference_value, :search_type_value, :routing_value, :track_total_hits_value
|
29
|
+
:timeout_value, :preference_value, :search_type_value, :routing_value, :track_total_hits_value,
|
30
|
+
:http_timeout_value
|
30
31
|
|
31
32
|
# Creates a new criteria while merging the attributes (constraints,
|
32
33
|
# settings, etc) of the current criteria with the attributes of another one
|
@@ -47,7 +48,7 @@ module SearchFlip
|
|
47
48
|
[
|
48
49
|
:profile_value, :failsafe_value, :terminate_after_value, :timeout_value, :offset_value,
|
49
50
|
:limit_value, :scroll_args, :source_value, :preference_value, :search_type_value,
|
50
|
-
:routing_value, :track_total_hits_value, :explain_value
|
51
|
+
:routing_value, :track_total_hits_value, :explain_value, :http_timeout_value
|
51
52
|
].each do |name|
|
52
53
|
criteria.send(:"#{name}=", other.send(name)) unless other.send(name).nil?
|
53
54
|
end
|
@@ -148,6 +149,22 @@ module SearchFlip
|
|
148
149
|
end
|
149
150
|
end
|
150
151
|
|
152
|
+
# Specifies a http timeout, such that a SearchFlip::TimeoutError will be
|
153
|
+
# thrown when the request times out.
|
154
|
+
#
|
155
|
+
# @example
|
156
|
+
# ProductIndex.http_timeout(3).search("hello world")
|
157
|
+
#
|
158
|
+
# @param value [Fixnum] The timeout value
|
159
|
+
#
|
160
|
+
# @return [SearchFlip::Criteria] A newly created extended criteria
|
161
|
+
|
162
|
+
def http_timeout(value)
|
163
|
+
fresh.tap do |criteria|
|
164
|
+
criteria.http_timeout_value = value
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
151
168
|
# Specifies early query termination, such that the processing will be
|
152
169
|
# stopped after the specified number of results has been accumulated.
|
153
170
|
#
|
@@ -330,10 +347,13 @@ module SearchFlip
|
|
330
347
|
dupped_request.delete(:from)
|
331
348
|
dupped_request.delete(:size)
|
332
349
|
|
350
|
+
http_request = connection.http_client
|
351
|
+
http_request = http_request.timeout(http_timeout_value) if http_timeout_value
|
352
|
+
|
333
353
|
if connection.version.to_i >= 5
|
334
|
-
|
354
|
+
http_request.post("#{target.type_url}/_delete_by_query", params: request_params.merge(params), json: dupped_request)
|
335
355
|
else
|
336
|
-
|
356
|
+
http_request.delete("#{target.type_url}/_query", params: request_params.merge(params), json: dupped_request)
|
337
357
|
end
|
338
358
|
|
339
359
|
target.refresh if SearchFlip::Config[:auto_refresh]
|
@@ -501,8 +521,8 @@ module SearchFlip
|
|
501
521
|
end
|
502
522
|
|
503
523
|
# Executes the search request for the current criteria, ie sends the
|
504
|
-
# request to Elasticsearch and returns the response. Connection
|
505
|
-
# response errors will be rescued if you specify the criteria to be
|
524
|
+
# request to Elasticsearch and returns the response. Connection, timeout
|
525
|
+
# and response errors will be rescued if you specify the criteria to be
|
506
526
|
# #failsafe, such that an empty response is returned instead.
|
507
527
|
#
|
508
528
|
# @example
|
@@ -590,6 +610,7 @@ module SearchFlip
|
|
590
610
|
|
591
611
|
def execute!
|
592
612
|
http_request = connection.http_client.headers(accept: "application/json")
|
613
|
+
http_request = http_request.timeout(http_timeout_value) if http_timeout_value
|
593
614
|
|
594
615
|
http_response =
|
595
616
|
if scroll_args && scroll_args[:id]
|
@@ -609,7 +630,7 @@ module SearchFlip
|
|
609
630
|
end
|
610
631
|
|
611
632
|
SearchFlip::Response.new(self, SearchFlip::JSON.parse(http_response.to_s))
|
612
|
-
rescue SearchFlip::ConnectionError, SearchFlip::ResponseError => e
|
633
|
+
rescue SearchFlip::ConnectionError, SearchFlip::TimeoutError, SearchFlip::ResponseError => e
|
613
634
|
raise e unless failsafe_value
|
614
635
|
|
615
636
|
SearchFlip::Response.new(self, "took" => 0, "hits" => { "total" => 0, "hits" => [] })
|
@@ -1,7 +1,28 @@
|
|
1
1
|
module SearchFlip
|
2
|
-
# The SearchFlip::HTTPClient class wraps the http gem
|
3
|
-
#
|
4
|
-
# with
|
2
|
+
# The SearchFlip::HTTPClient class wraps the http gem and responsible for the
|
3
|
+
# http request/response handling, ie communicating with Elasticsearch. You
|
4
|
+
# only need to use it directly if you need authentication to communicate with
|
5
|
+
# Elasticsearch or if you want to set some custom http settings.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# http_client = SearchFlip::HTTPClient.new
|
9
|
+
#
|
10
|
+
# # Basic Auth
|
11
|
+
# http_client = http_client.basic_auth(user: "username", pass: "password")
|
12
|
+
#
|
13
|
+
# # Raw Auth Header
|
14
|
+
# http_client = http_client.auth("Bearer VGhlIEhUVFAgR2VtLCBST0NLUw")
|
15
|
+
#
|
16
|
+
# # Proxy Settings
|
17
|
+
# http_client = http_client.via("proxy.host", 8080)
|
18
|
+
#
|
19
|
+
# # Custom headers
|
20
|
+
# http_client = http_client.headers(key: "value")
|
21
|
+
#
|
22
|
+
# # Timeouts
|
23
|
+
# http_client = http_client.timeout(20)
|
24
|
+
#
|
25
|
+
# SearchFlip::Connection.new(base_url: "...", http_client: http_client)
|
5
26
|
|
6
27
|
class HTTPClient
|
7
28
|
attr_accessor :request, :plugins
|
@@ -14,11 +35,11 @@ module SearchFlip
|
|
14
35
|
class << self
|
15
36
|
extend Forwardable
|
16
37
|
|
17
|
-
def_delegators :new, :headers, :via, :basic_auth, :auth
|
38
|
+
def_delegators :new, :headers, :via, :basic_auth, :auth, :timeout
|
18
39
|
def_delegators :new, :get, :post, :put, :delete, :head
|
19
40
|
end
|
20
41
|
|
21
|
-
[:headers, :via, :basic_auth, :auth].each do |method|
|
42
|
+
[:headers, :via, :basic_auth, :auth, :timeout].each do |method|
|
22
43
|
define_method method do |*args|
|
23
44
|
dup.tap do |client|
|
24
45
|
client.request = request.send(method, *args)
|
@@ -45,6 +66,10 @@ module SearchFlip
|
|
45
66
|
response
|
46
67
|
rescue HTTP::ConnectionError => e
|
47
68
|
raise SearchFlip::ConnectionError, e.message
|
69
|
+
rescue HTTP::TimeoutError => e
|
70
|
+
raise SearchFlip::TimeoutError, e.message
|
71
|
+
rescue HTTP::Error => e
|
72
|
+
raise SearchFlip::HttpError, e.message
|
48
73
|
end
|
49
74
|
end
|
50
75
|
end
|
data/lib/search_flip/index.rb
CHANGED
@@ -254,7 +254,7 @@ module SearchFlip
|
|
254
254
|
:page, :per, :search, :highlight, :suggest, :custom, :find_in_batches, :find_results_in_batches,
|
255
255
|
:find_each, :find_each_result, :failsafe, :total_entries, :total_count, :timeout, :terminate_after,
|
256
256
|
:records, :results, :must, :must_not, :should, :preference, :search_type, :routing,
|
257
|
-
:track_total_hits, :explain
|
257
|
+
:track_total_hits, :explain, :http_timeout
|
258
258
|
|
259
259
|
# Override to specify the type name used within Elasticsearch. Recap,
|
260
260
|
# this gem uses an individual index for each index class, because
|
data/lib/search_flip/json.rb
CHANGED
@@ -1,22 +1,11 @@
|
|
1
1
|
module SearchFlip
|
2
2
|
class JSON
|
3
|
-
@default_options = {
|
4
|
-
mode: :custom,
|
5
|
-
use_to_json: true,
|
6
|
-
time_format: :xmlschema,
|
7
|
-
bigdecimal_as_decimal: false
|
8
|
-
}
|
9
|
-
|
10
|
-
def self.default_options
|
11
|
-
@default_options
|
12
|
-
end
|
13
|
-
|
14
3
|
def self.generate(obj)
|
15
|
-
Oj.dump(obj,
|
4
|
+
Oj.dump(obj, SearchFlip::Config[:json_options])
|
16
5
|
end
|
17
6
|
|
18
7
|
def self.parse(json)
|
19
|
-
|
8
|
+
::JSON.parse(json)
|
20
9
|
end
|
21
10
|
end
|
22
11
|
end
|
data/lib/search_flip/version.rb
CHANGED
data/search_flip.gemspec
CHANGED
@@ -97,7 +97,8 @@ RSpec.describe SearchFlip::Criteria do
|
|
97
97
|
methods = [
|
98
98
|
:profile_value, :failsafe_value, :terminate_after_value, :timeout_value,
|
99
99
|
:offset_value, :limit_value, :scroll_args, :source_value, :preference_value,
|
100
|
-
:search_type_value, :routing_value, :track_total_hits_value, :explain_value
|
100
|
+
:search_type_value, :routing_value, :track_total_hits_value, :explain_value,
|
101
|
+
:http_timeout_value
|
101
102
|
]
|
102
103
|
|
103
104
|
methods.each do |method|
|
@@ -191,6 +192,22 @@ RSpec.describe SearchFlip::Criteria do
|
|
191
192
|
end
|
192
193
|
end
|
193
194
|
|
195
|
+
describe "#http_timeout" do
|
196
|
+
it "sets the query timeout" do
|
197
|
+
http_client = double("client").as_null_object
|
198
|
+
allow(http_client).to receive(:timeout).and_return(http_client)
|
199
|
+
allow(http_client).to receive(:post).and_raise(SearchFlip::TimeoutError)
|
200
|
+
allow(ProductIndex.connection).to receive(:http_client).and_return(http_client)
|
201
|
+
|
202
|
+
expect { ProductIndex.http_timeout(1).execute }.to raise_error(SearchFlip::TimeoutError)
|
203
|
+
expect(http_client).to have_received(:timeout).with(1)
|
204
|
+
end
|
205
|
+
|
206
|
+
it "executes without errors" do
|
207
|
+
expect { ProductIndex.http_timeout(1).execute }.not_to raise_error
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
194
211
|
describe "#terminate_after" do
|
195
212
|
it "sets the terminate after value" do
|
196
213
|
query = ProductIndex.terminate_after(1)
|
@@ -1204,13 +1221,19 @@ RSpec.describe SearchFlip::Criteria do
|
|
1204
1221
|
end
|
1205
1222
|
|
1206
1223
|
describe "#failsafe" do
|
1207
|
-
|
1208
|
-
|
1224
|
+
[SearchFlip::ConnectionError, SearchFlip::TimeoutError, SearchFlip::ResponseError.new(code: "code", body: "body")].each do |error|
|
1225
|
+
it "prevents #{error}" do
|
1226
|
+
http_client = double("client").as_null_object
|
1227
|
+
allow(http_client).to receive(:post).and_raise(error)
|
1228
|
+
allow(ProductIndex.connection).to receive(:http_client).and_return(http_client)
|
1229
|
+
|
1230
|
+
expect { ProductIndex.all.execute }.to raise_error(error)
|
1209
1231
|
|
1210
|
-
|
1232
|
+
query = ProductIndex.failsafe(true)
|
1211
1233
|
|
1212
|
-
|
1213
|
-
|
1234
|
+
expect(query.records).to eq([])
|
1235
|
+
expect(query.total_entries).to eq(0)
|
1236
|
+
end
|
1214
1237
|
end
|
1215
1238
|
end
|
1216
1239
|
|
@@ -7,7 +7,7 @@ class HttpTestRequest
|
|
7
7
|
self.calls = []
|
8
8
|
end
|
9
9
|
|
10
|
-
[:via, :basic_auth, :auth].each do |method|
|
10
|
+
[:headers, :via, :basic_auth, :auth, :timeout].each do |method|
|
11
11
|
define_method method do |*args|
|
12
12
|
dup.tap do |request|
|
13
13
|
request.calls = calls + [[method, args]]
|
@@ -20,7 +20,7 @@ RSpec.describe SearchFlip::HTTPClient do
|
|
20
20
|
describe "delegation" do
|
21
21
|
subject { SearchFlip::HTTPClient }
|
22
22
|
|
23
|
-
[:headers, :via, :basic_auth, :auth].each do |method|
|
23
|
+
[:headers, :via, :basic_auth, :auth, :timeout].each do |method|
|
24
24
|
it { should delegate(method).to(:new) }
|
25
25
|
end
|
26
26
|
|
@@ -56,8 +56,12 @@ RSpec.describe SearchFlip::HTTPClient do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
[:via, :basic_auth, :auth].each do |method|
|
59
|
+
[:headers, :via, :basic_auth, :auth, :timeout].each do |method|
|
60
60
|
describe "##{method}" do
|
61
|
+
it "is understood by HTTP" do
|
62
|
+
expect(HTTP.respond_to?(method)).to eq(true)
|
63
|
+
end
|
64
|
+
|
61
65
|
it "creates a dupped instance" do
|
62
66
|
client = SearchFlip::HTTPClient.new
|
63
67
|
client.request = HttpTestRequest.new
|
@@ -14,7 +14,7 @@ RSpec.describe SearchFlip::Index do
|
|
14
14
|
:total_entries, :total_count, :terminate_after, :timeout, :records, :results,
|
15
15
|
:must, :must_not, :should, :find_each_result,
|
16
16
|
:find_results_in_batches, :preference, :search_type, :routing,
|
17
|
-
:track_total_hits, :explain
|
17
|
+
:track_total_hits, :explain, :http_timeout
|
18
18
|
]
|
19
19
|
|
20
20
|
methods.each do |method|
|
@@ -32,14 +32,14 @@ RSpec.describe SearchFlip::JSON do
|
|
32
32
|
expect(described_class.parse('{"key":"value"}')).to eq("key" => "value")
|
33
33
|
end
|
34
34
|
|
35
|
-
it "delegates to
|
36
|
-
allow(
|
35
|
+
it "delegates to JSON" do
|
36
|
+
allow(JSON).to receive(:parse)
|
37
37
|
|
38
38
|
payload = '{"key":"value"}'
|
39
39
|
|
40
40
|
described_class.parse(payload)
|
41
41
|
|
42
|
-
expect(
|
42
|
+
expect(JSON).to have_received(:parse).with(payload)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_flip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0.
|
4
|
+
version: 4.0.0.beta9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Vetter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -164,6 +164,20 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: json
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: oj
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|