algoliasearch 1.3.0 → 1.3.1

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: c4329565282764c298bfea3ca19ae79b950a3221
4
- data.tar.gz: cec3814f851200497f6c725eb6828da43c6c42bd
3
+ metadata.gz: 6815aa98febd670b9ee776ed86899d1b1f813c4b
4
+ data.tar.gz: f5a69438b609bcbe2e70b04fb53c60c51ad007c9
5
5
  SHA512:
6
- metadata.gz: 478083554dec799684b0cc34096063ae127aad3d42ca8e08a46a7b7b356819f34c487aa3776f9ac9aa5585cd0cc2cb160baadc0a7b516da6ce00b000f1b0947f
7
- data.tar.gz: f0f4e50441de3d2047f07987fedabbf3ee9a22a2ed6db8ba62a55f2468fb37bd258d526ccd2bd8beed03645d1dde20400d33dd328554110e362da8560a5a94db
6
+ metadata.gz: 5226f954185110c75e6d6c12081139a574f9e1f6fd3579d53d92e32d48e959dde1dd2da8a4407fe0980a2b6b44852e97b0ba6eaee5ab1517ea9dbf433ed0601d
7
+ data.tar.gz: c2fa093f6517079ad36aba007bdcf59eb0f6f91209160aaa6c4ebc72a795c4ac44d30f47a45afb0fb41942623f262a0ddaeadaa4e789345daa503b609ee52f4c
data/ChangeLog CHANGED
@@ -1,9 +1,18 @@
1
1
  CHANGELOG
2
2
 
3
- 2014-11-29 1.3.0
3
+ 2014-11-29 1.3.1
4
+ * Fixed wrong deployed version (1.3.0 was based on 1.2.13 instead of 1.2.14)
4
5
 
6
+ 2014-11-29 1.3.0
5
7
  * Use algolia.net domain instead of algolia.io
6
8
 
9
+ 2014-11-10 1.2.14
10
+ * Force the underlying httpclient dependency to be >= 2.4 in the gemspec as well
11
+ * Ability to force the SSL version
12
+
13
+ 2014-10-22 1.2.13
14
+ * Fix the loop on hosts to retry when the http code is different than 200, 201, 400, 403, 404
15
+
7
16
  2014-10-08 1.2.12
8
17
 
9
18
  * Upgrade to httpclient 2.4
@@ -50,17 +50,17 @@ Gem::Specification.new do |s|
50
50
  s.specification_version = 4
51
51
 
52
52
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
- s.add_runtime_dependency(%q<httpclient>, ["~> 2.3"])
53
+ s.add_runtime_dependency(%q<httpclient>, ["~> 2.4"])
54
54
  s.add_runtime_dependency(%q<json>, [">= 1.5.1"])
55
55
  s.add_development_dependency "travis"
56
56
  s.add_development_dependency "rake"
57
57
  s.add_development_dependency "rdoc"
58
58
  else
59
- s.add_dependency(%q<httpclient>, ["~> 2.3"])
59
+ s.add_dependency(%q<httpclient>, ["~> 2.4"])
60
60
  s.add_dependency(%q<json>, [">= 1.5.1"])
61
61
  end
62
62
  else
63
- s.add_dependency(%q<httpclient>, ["~> 2.3"])
63
+ s.add_dependency(%q<httpclient>, ["~> 2.4"])
64
64
  s.add_dependency(%q<json>, [">= 1.5.1"])
65
65
  end
66
66
  end
@@ -10,11 +10,12 @@ module Algolia
10
10
  # A class which encapsulates the HTTPS communication with the Algolia
11
11
  # API server. Uses the HTTPClient library for low-level HTTP communication.
12
12
  class Client
13
- attr_reader :ssl, :hosts, :application_id, :api_key, :headers, :connect_timeout, :send_timeout, :receive_timeout, :search_timeout
13
+ attr_reader :ssl, :ssl_version, :hosts, :application_id, :api_key, :headers, :connect_timeout, :send_timeout, :receive_timeout, :search_timeout
14
14
 
15
15
 
16
16
  def initialize(data = {})
17
17
  @ssl = data[:ssl].nil? ? true : data[:ssl]
18
+ @ssl_version = data[:ssl_version].nil? ? nil : data[:ssl_version]
18
19
  @application_id = data[:application_id]
19
20
  @api_key = data[:api_key]
20
21
  @hosts = (data[:hosts] || 1.upto(3).map { |i| "#{@application_id}-#{i}.algolia.net" }).shuffle
@@ -40,7 +41,7 @@ module Algolia
40
41
  begin
41
42
  return perform_request(host[:session], host[:base_url] + uri, method, data)
42
43
  rescue AlgoliaProtocolError => e
43
- raise if e.code != Protocol::ERROR_TIMEOUT and e.code != Protocol::ERROR_UNAVAILABLE
44
+ raise if e.code == Protocol::ERROR_BAD_REQUEST or e.code == Protocol::ERROR_FORBIDDEN or e.code == Protocol::ERROR_NOT_FOUND
44
45
  exceptions << e
45
46
  rescue => e
46
47
  exceptions << e
@@ -76,9 +77,11 @@ module Algolia
76
77
  def thread_local_hosts(forced_timeout)
77
78
  Thread.current[:algolia_hosts] ||= {}
78
79
  Thread.current[:algolia_hosts][forced_timeout.to_s] ||= hosts.map do |host|
80
+ client = HTTPClient.new
81
+ client.ssl_config.ssl_version = @ssl_version if @ssl && @ssl_version
79
82
  hinfo = {
80
83
  :base_url => "http#{@ssl ? 's' : ''}://#{host}",
81
- :session => HTTPClient.new
84
+ :session => client
82
85
  }
83
86
  hinfo[:session].transparent_gzip_decompression = true
84
87
  hinfo[:session].connect_timeout = @connect_timeout if @connect_timeout
data/lib/algolia/index.rb CHANGED
@@ -232,27 +232,34 @@ module Algolia
232
232
  #
233
233
  # @param obj the object attributes to override
234
234
  # @param objectID the associated objectID, if nil 'obj' must contain an 'objectID' key
235
+ # @param create_if_not_exits a boolean, if true creates the object if this one doesn't exist
235
236
  #
236
- def partial_update_object(obj, objectID = nil)
237
- Algolia.client.post(Protocol.partial_object_uri(name, get_objectID(obj, objectID)), obj.to_json)
237
+ def partial_update_object(obj, objectID = nil, create_if_not_exits = true)
238
+ Algolia.client.post(Protocol.partial_object_uri(name, get_objectID(obj, objectID), create_if_not_exits), obj.to_json)
238
239
  end
239
240
 
240
241
  #
241
242
  # Partially Override the content of several objects
242
243
  #
243
244
  # @param objs an array of objects to update (each object must contains a objectID attribute)
245
+ # @param create_if_not_exits a boolean, if true create the objects if they don't exist
244
246
  #
245
- def partial_update_objects(objs)
246
- batch build_batch('partialUpdateObject', objs, true)
247
+ def partial_update_objects(objs, create_if_not_exits = true)
248
+ if create_if_not_exits
249
+ batch build_batch('partialUpdateObject', objs, true)
250
+ else
251
+ batch build_batch('partialUpdateObjectNoCreate', objs, true)
252
+ end
247
253
  end
248
254
 
249
255
  #
250
256
  # Partially Override the content of several objects and wait end of indexing
251
257
  #
252
258
  # @param objs an array of objects to update (each object must contains a objectID attribute)
259
+ # @param create_if_not_exits a boolean, if true create the objects if they don't exist
253
260
  #
254
- def partial_update_objects!(objs)
255
- res = partial_update_objects(objs)
261
+ def partial_update_objects!(objs, create_if_not_exits = true)
262
+ res = partial_update_objects(objs, create_if_not_exits)
256
263
  wait_task(res["taskID"])
257
264
  return res
258
265
  end
@@ -262,9 +269,10 @@ module Algolia
262
269
  #
263
270
  # @param obj the attributes to override
264
271
  # @param objectID the associated objectID, if nil 'obj' must contain an 'objectID' key
272
+ # @param create_if_not_exits a boolean, if true creates the object if this one doesn't exist
265
273
  #
266
- def partial_update_object!(obj, objectID = nil)
267
- res = partial_update_object(obj, objectID)
274
+ def partial_update_object!(obj, objectID = nil, create_if_not_exits = true)
275
+ res = partial_update_object(obj, objectID, create_if_not_exits)
268
276
  wait_task(res["taskID"])
269
277
  return res
270
278
  end
@@ -27,8 +27,9 @@ module Algolia
27
27
  # HTTP ERROR CODES
28
28
  # ----------------------------------------
29
29
 
30
- ERROR_TIMEOUT = 124
31
- ERROR_UNAVAILABLE = 503
30
+ ERROR_BAD_REQUEST = 400
31
+ ERROR_FORBIDDEN = 403
32
+ ERROR_NOT_FOUND = 404
32
33
 
33
34
  # URI Helpers
34
35
  # ----------------------------------------
@@ -78,8 +79,9 @@ module Algolia
78
79
  "#{index_uri(index)}/browse#{params}"
79
80
  end
80
81
 
81
- def Protocol.partial_object_uri(index, object_id)
82
- "#{index_uri(index)}/#{CGI.escape(object_id)}/partial"
82
+ def Protocol.partial_object_uri(index, object_id, create_if_not_exits = true)
83
+ params = create_if_not_exits ? "" : "?createIfNotExists=false"
84
+ "#{index_uri(index)}/#{CGI.escape(object_id)}/partial#{params}"
83
85
  end
84
86
 
85
87
  def Protocol.settings_uri(index)
@@ -1,3 +1,3 @@
1
1
  module Algolia
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.1"
3
3
  end
@@ -9,40 +9,40 @@ end
9
9
  WebMock.disable!
10
10
 
11
11
  # list indexes
12
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/indexes/).to_return(:body => '{ "items": [] }')
12
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes/).to_return(:body => '{ "items": [] }')
13
13
  # query index
14
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/indexes\/[^\/]+/).to_return(:body => '{}')
15
- WebMock.stub_request(:post, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/query/).to_return(:body => '{}')
14
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+/).to_return(:body => '{}')
15
+ WebMock.stub_request(:post, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/query/).to_return(:body => '{}')
16
16
  # delete index
17
- WebMock.stub_request(:delete, /.*\.algolia\.io\/1\/indexes\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
17
+ WebMock.stub_request(:delete, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
18
18
  # clear index
19
- WebMock.stub_request(:post, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/clear/).to_return(:body => '{ "taskID": 42 }')
19
+ WebMock.stub_request(:post, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/clear/).to_return(:body => '{ "taskID": 42 }')
20
20
  # add object
21
- WebMock.stub_request(:post, /.*\.algolia\.io\/1\/indexes\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
21
+ WebMock.stub_request(:post, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
22
22
  # save object
23
- WebMock.stub_request(:put, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
23
+ WebMock.stub_request(:put, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
24
24
  # partial update
25
- WebMock.stub_request(:put, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/[^\/]+\/partial/).to_return(:body => '{ "taskID": 42 }')
25
+ WebMock.stub_request(:put, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/[^\/]+\/partial/).to_return(:body => '{ "taskID": 42 }')
26
26
  # get object
27
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/[^\/]+/).to_return(:body => '{}')
27
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/[^\/]+/).to_return(:body => '{}')
28
28
  # delete object
29
- WebMock.stub_request(:delete, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
29
+ WebMock.stub_request(:delete, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
30
30
  # batch
31
- WebMock.stub_request(:post, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/batch/).to_return(:body => '{ "taskID": 42 }')
31
+ WebMock.stub_request(:post, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/batch/).to_return(:body => '{ "taskID": 42 }')
32
32
  # settings
33
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/settings/).to_return(:body => '{}')
34
- WebMock.stub_request(:put, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/settings/).to_return(:body => '{ "taskID": 42 }')
33
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/settings/).to_return(:body => '{}')
34
+ WebMock.stub_request(:put, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/settings/).to_return(:body => '{ "taskID": 42 }')
35
35
  # browse
36
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/browse/).to_return(:body => '{}')
36
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/browse/).to_return(:body => '{}')
37
37
  # operations
38
- WebMock.stub_request(:post, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/operation/).to_return(:body => '{ "taskID": 42 }')
38
+ WebMock.stub_request(:post, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/operation/).to_return(:body => '{ "taskID": 42 }')
39
39
  # tasks
40
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/task\/[^\/]+/).to_return(:body => '{ "status": "published" }')
40
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/task\/[^\/]+/).to_return(:body => '{ "status": "published" }')
41
41
  # index keys
42
- WebMock.stub_request(:post, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/keys/).to_return(:body => '{ }')
43
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/indexes\/[^\/]+\/keys/).to_return(:body => '{ "keys": [] }')
42
+ WebMock.stub_request(:post, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/keys/).to_return(:body => '{ }')
43
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/keys/).to_return(:body => '{ "keys": [] }')
44
44
  # global keys
45
- WebMock.stub_request(:post, /.*\.algolia\.io\/1\/keys/).to_return(:body => '{ }')
46
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/keys/).to_return(:body => '{ "keys": [] }')
47
- WebMock.stub_request(:get, /.*\.algolia\.io\/1\/keys\/[^\/]+/).to_return(:body => '{ }')
48
- WebMock.stub_request(:delete, /.*\.algolia\.io\/1\/keys\/[^\/]+/).to_return(:body => '{ }')
45
+ WebMock.stub_request(:post, /.*\.algolia\.(io|net)\/1\/keys/).to_return(:body => '{ }')
46
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/keys/).to_return(:body => '{ "keys": [] }')
47
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/keys\/[^\/]+/).to_return(:body => '{ }')
48
+ WebMock.stub_request(:delete, /.*\.algolia\.(io|net)\/1\/keys\/[^\/]+/).to_return(:body => '{ }')
data/spec/client_spec.rb CHANGED
@@ -42,6 +42,41 @@ describe 'Client' do
42
42
  res["hits"].length.should eq(1)
43
43
  end
44
44
 
45
+ it "should partial update a simple object, or add it if it doesn't exist" do
46
+ res = @index.search("tonny@parker.org")
47
+ res["hits"].length.should eq(0)
48
+ @index.partial_update_object!({ :email => "tonny@parker.org" }, "1")
49
+ res = @index.search("tonny@parker.org")
50
+ res["hits"].length.should eq(1)
51
+ end
52
+
53
+ it "should partial update a simple object, but don't add it if it doesn't exist" do
54
+ @index.partial_update_object!({ :email => "alex@boom.org" }, "51", false)
55
+ res = @index.search("alex@boom.org")
56
+ res["hits"].length.should eq(0)
57
+ end
58
+
59
+ it "should partial update a batch of objects, and add them if they don't exist" do
60
+ batch = [
61
+ { :objectID => "1", :email => "john@wanna.org" },
62
+ { :objectID => "2", :email => "robert@wanna.org" }
63
+ ]
64
+ @index.partial_update_objects!(batch)
65
+ res = @index.search("@wanna.org")
66
+ res["hits"].length.should eq(2)
67
+ end
68
+
69
+ it "should partial update a batch of objects, but don't add them if they don't exist" do
70
+ create_if_not_exits = false
71
+ batch = [
72
+ { :objectID => "11", :email => "john@be.org" },
73
+ { :objectID => "22", :email => "robert@be.org" }
74
+ ]
75
+ @index.partial_update_objects!(batch, create_if_not_exits)
76
+ res = @index.search("@be.org")
77
+ res["hits"].length.should eq(0)
78
+ end
79
+
45
80
  it "should add a set of objects" do
46
81
  @index.add_objects!([
47
82
  { :name => "Another", :email => "another1@example.org" },
@@ -685,3 +720,4 @@ describe 'Client' do
685
720
  answer['disjunctiveFacets']['stars']['****'].should eq(1)
686
721
  end
687
722
  end
723
+
data/spec/stub_spec.rb CHANGED
@@ -10,7 +10,7 @@ describe 'With a rate limited client' do
10
10
  end
11
11
 
12
12
  it "should pass the right headers" do
13
- WebMock.stub_request(:get, %r{https://.*\.algolia\.io/1/indexes/friends\?query=.*}).
13
+ WebMock.stub_request(:get, %r{https://.*\.algolia\.(io|net)/1/indexes/friends\?query=.*}).
14
14
  with(:headers => {'Content-Type'=>'application/json; charset=utf-8', 'User-Agent'=>"Algolia for Ruby #{Algolia::VERSION}", 'X-Algolia-Api-Key'=>ENV['ALGOLIA_API_KEY'], 'X-Algolia-Application-Id'=>ENV['ALGOLIA_APPLICATION_ID'], 'X-Forwarded-Api-Key'=>'ratelimitapikey', 'X-Forwarded-For'=>'1.2.3.4'}).
15
15
  to_return(:status => 200, :body => "{ \"hits\": [], \"fakeAttribute\": 1 }", :headers => {})
16
16
  Algolia.enable_rate_limit_forward ENV['ALGOLIA_API_KEY'], "1.2.3.4", "ratelimitapikey"
@@ -20,7 +20,7 @@ describe 'With a rate limited client' do
20
20
  end
21
21
 
22
22
  it "should use original headers" do
23
- WebMock.stub_request(:get, %r{https://.*\.algolia\.io/1/indexes/friends\?query=.*}).
23
+ WebMock.stub_request(:get, %r{https://.*\.algolia\.(io|net)/1/indexes/friends\?query=.*}).
24
24
  with(:headers => {'Content-Type'=>'application/json; charset=utf-8', 'User-Agent'=>"Algolia for Ruby #{Algolia::VERSION}", 'X-Algolia-Api-Key'=>ENV['ALGOLIA_API_KEY'], 'X-Algolia-Application-Id'=>ENV['ALGOLIA_APPLICATION_ID'] }).
25
25
  to_return(:status => 200, :body => "{ \"hits\": [], \"fakeAttribute\": 2 }", :headers => {})
26
26
  Algolia.disable_rate_limit_forward
@@ -29,7 +29,7 @@ describe 'With a rate limited client' do
29
29
  end
30
30
 
31
31
  it "should pass the right headers in the scope" do
32
- WebMock.stub_request(:get, %r{https://.*\.algolia\.io/1/indexes/friends\?query=.*}).
32
+ WebMock.stub_request(:get, %r{https://.*\.algolia\.(io|net)/1/indexes/friends\?query=.*}).
33
33
  with(:headers => {'Content-Type'=>'application/json; charset=utf-8', 'User-Agent'=>"Algolia for Ruby #{Algolia::VERSION}", 'X-Algolia-Api-Key'=>ENV['ALGOLIA_API_KEY'], 'X-Algolia-Application-Id'=>ENV['ALGOLIA_APPLICATION_ID'], 'X-Forwarded-Api-Key'=>'ratelimitapikey', 'X-Forwarded-For'=>'1.2.3.4'}).
34
34
  to_return(:status => 200, :body => "{ \"hits\": [], \"fakeAttribute\": 1 }", :headers => {})
35
35
  Algolia.with_rate_limits "1.2.3.4", "ratelimitapikey" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algoliasearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Algolia
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.3'
19
+ version: '2.4'
20
20
  type: :runtime
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: '2.3'
26
+ version: '2.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json
29
29
  requirement: !ruby/object:Gem::Requirement