orchestrate 0.9.1 → 0.9.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9ba0193a1085b054d2ebb2e472e746a377b785bd
4
- data.tar.gz: 41d3c58e1d7959c33fdfdb3b4bb6d86d8aa1d554
3
+ metadata.gz: 7ea84118d96674889b76ea3cad03c131e6339aa5
4
+ data.tar.gz: d3c664b057f0af8e147060413ab9a43d96b2ae9f
5
5
  SHA512:
6
- metadata.gz: 2b6857d31ce13850286561cdfab4c144af59083ad0f26d8a9a1349c633a99453720a6f4f091e72521467b0fc5efa628b4a65aeec95483021789889c8dd96ba58
7
- data.tar.gz: 1fdddf125332d0bfeb2bd84b42b772df0b7a770bf757812ca61a3301927a5970e2f042540be55a1778ec3f30ffee23d8dec653f2631db69c8f4832d903536e2c
6
+ metadata.gz: 7eb7729c1590a618715870997959990b8d4ac057ab240eb15109d704cb3277ad146c1b92de958c3a6259ce56656b0f1fd273ea86e0b32b4bbec734aa8381ad1e
7
+ data.tar.gz: 8a01ed2702ec401ec9d88628e2b2005a6c1511af13bf0596d051c934d7165e95ac19a00a4c27685b8a1a9bff8832e93bd91a94198f2daec14d802a680cef2afb
data/README.md CHANGED
@@ -18,6 +18,15 @@ app = Orchestrate::Application.new(api_key)
18
18
  users = app[:users]
19
19
  ```
20
20
 
21
+ #### Changing Data centers
22
+
23
+ By default, the host data center is AWS US East (https://api.orchestrate.io). To use another data center, such as AWS EU West, then you must initialize the client with the host URL http://api.aws-eu-west-1.orchestrate.io/.
24
+
25
+ ```ruby
26
+ host = "https://api.aws-eu-west-1.orchestrate.io/"
27
+ app = Orchestrate::Application.new(api_key, host)
28
+ ```
29
+
21
30
  #### Store some KeyValues, List them
22
31
  ```ruby
23
32
  users[:joe] = { "name" => "Joe" } # PUTs joe, returns the input, as per Ruby convention on #[]=
@@ -36,12 +45,34 @@ jill.value # { "name" => "Jill", "location" =>
36
45
  jill.save # PUT-If-Match, updates ref
37
46
  ```
38
47
 
48
+ #### Searching, Sorting for KeyValues
49
+ ```ruby
50
+ users.search("name:Jill") # returns users with name "Jill"
51
+ users.search("name:Jill").order(:created_at) # returns users with name "Jill" in ascending order
52
+ ```
53
+
54
+ The `order` method accepts multiple arguments, allowing you to sort search results based multiple parameters. When providing multiple field names to sort by each even-numbered argument must be either `:asc` or `:desc`.
55
+
56
+ ```ruby
57
+ users.search("location: Portland").order(:name, :asc, :rank, :desc)
58
+ ```
59
+
60
+ By default, odd-numbered arguments will be sorted in ascending order.
61
+ ```ruby
62
+ users.search("location: Portland").order(:name) # returns users in ascending order by name
63
+ users.search("location: Portland").order(:name, :asc, :rank, :desc, :created_at) # :created_at argument defaults to :asc
64
+ ```
65
+
39
66
  ### Method Client use
40
67
 
41
68
  #### Create a Client
42
69
  ``` ruby
43
70
  # method client
44
71
  client = Orchestrate::Client.new(api_key)
72
+
73
+ # EU data center
74
+ host = "https://api.aws-eu-west-1.orchestrate.io/"
75
+ client = Orchestrate::Client.new(api_key, host)
45
76
  ```
46
77
 
47
78
  #### Query Collections, Keys and Values
@@ -53,6 +84,18 @@ client.delete(:users, :jack, jack.ref) # DELETE-If-Match, returns API::Resp
53
84
  client.list(:users) # LIST users, returns API::CollectionResposne
54
85
  ```
55
86
 
87
+ #### Search Collections
88
+ ```ruby
89
+ client.search(:users, "location:Portland") # search 'users' collection for items with a location of 'Portland'
90
+ ```
91
+
92
+ #### Sorting Collections
93
+ ```ruby
94
+ client.search(:users, "location:Portland", { sort: "value.name:desc" }) # returns items sorted by a field name in descending order
95
+ client.search(:users, "location:Portland", { sort: "value.name:asc" }) # returns items sorted by a field name in ascending order
96
+ client.search(:users, "location:Portland", { sort: "value.name.last:asc,value.name.first:asc" }) # returns items sorted primarily by last name, but whenever two users have an identical last name, the results will be sorted by first name as well.
97
+ ```
98
+
56
99
  ### Examples and Documentation
57
100
 
58
101
  There are more examples at [Orchestrate's API Documentation][apidoc] and documentation in the [rdoc][].
@@ -157,6 +200,10 @@ end
157
200
 
158
201
  ## Release Notes
159
202
 
203
+ ### November 19, 2014: release 0.9.2
204
+ - Implement `SearchResults#order`, allowing `Collection` object results to be sorted.
205
+ - Implement Data Center choice on `Orchestrate::Client` and `Orchestrate::Application`.
206
+
160
207
  ### October 8, 2014: release 0.9.1
161
208
  - Improvements to documentation.
162
209
 
@@ -6,6 +6,9 @@ module Orchestrate
6
6
  # @return [String] The API key provided
7
7
  attr_reader :api_key
8
8
 
9
+ # @return [String] The Orchestrate data center URL
10
+ attr_reader :host
11
+
9
12
  # @return [Orchestrate::Client] The client tied to this application.
10
13
  attr_reader :client
11
14
 
@@ -13,13 +16,15 @@ module Orchestrate
13
16
  # @param client_or_api_key [Orchestrate::Client, #to_s] A client instantiated with the API key and faraday setup, or the API key for your Orchestrate Application.
14
17
  # @yieldparam [Faraday::Connection] connection Setup for the Faraday connection.
15
18
  # @return Orchestrate::Application
16
- def initialize(client_or_api_key, &client_setup)
19
+ def initialize(client_or_api_key, host="https://api.orchestrate.io", &client_setup)
17
20
  if client_or_api_key.kind_of?(Orchestrate::Client)
18
21
  @client = client_or_api_key
19
22
  @api_key = client.api_key
23
+ @host = client.host
20
24
  else
21
25
  @api_key = client_or_api_key
22
- @client = Client.new(api_key, &client_setup)
26
+ @host = host
27
+ @client = Client.new(api_key, host, &client_setup)
23
28
  end
24
29
  client.ping
25
30
  end
@@ -10,6 +10,9 @@ module Orchestrate
10
10
  # @return [String] The API key provided
11
11
  attr_reader :api_key
12
12
 
13
+ # @return [String] The Orchestrate data center URL
14
+ attr_reader :host
15
+
13
16
  # @return [Faraday::Connection] The Faraday HTTP connection.
14
17
  attr_reader :http
15
18
 
@@ -18,13 +21,15 @@ module Orchestrate
18
21
 
19
22
  # Instantiate a new Client for an Orchestrate application.
20
23
  # @param api_key [#to_s] The API Key for your Orchestrate application.
24
+ # @param host [#to_s] The host datacenter for your Orchestrate application.
21
25
  # @yieldparam [Faraday::Connection] The setup for the faraday connection.
22
26
  # @return Orchestrate::Client
23
27
  # @todo api_key -> app_url, parse api_key from auth section of url
24
- def initialize(api_key, &block)
28
+ def initialize(api_key, host="https://api.orchestrate.io", &block)
25
29
  @api_key = api_key
30
+ @host = host
26
31
  @faraday_configuration = block
27
- @http = Faraday.new("https://api.orchestrate.io") do |faraday|
32
+ @http = Faraday.new(@host) do |faraday|
28
33
  block = lambda{|f| f.adapter :net_http_persistent } unless block
29
34
  block.call faraday
30
35
 
@@ -131,7 +136,7 @@ module Orchestrate
131
136
  # @param collection [#to_s] The name of the collection.
132
137
  # @param key [#to_s] The name of the key.
133
138
  # @param body [#to_json] The value for the key.
134
- # @param condition [String, false, nil] Conditions for setting the value.
139
+ # @param condition [String, false, nil] Conditions for setting the value.
135
140
  # If `String`, value used as `If-Match`, value will only be updated if key's current value's ref matches.
136
141
  # If `false`, uses `If-None-Match` the value will only be set if there is no existent value for the key.
137
142
  # If `nil` (default), value is set regardless.
@@ -364,6 +364,9 @@ module Orchestrate
364
364
 
365
365
  # @return [#to_s] The Lucene Query String given as the search query.
366
366
  attr_reader :query
367
+
368
+ # @return [#to_s] The sorting parameters.
369
+ attr_reader :sort
367
370
 
368
371
  # @return [Integer] The number of results to fetch per request.
369
372
  attr_reader :limit
@@ -371,12 +374,24 @@ module Orchestrate
371
374
  # Initialize a new SearchResults object
372
375
  # @param collection [Orchestrate::Collection] The collection to search.
373
376
  # @param query [#to_s] The Lucene Query to perform.
374
- def initialize(collection, query)
377
+ def initialize(collection, query, sort=nil)
375
378
  @collection = collection
376
379
  @query = query
380
+ @sort = sort
377
381
  @limit = 100
378
382
  @offset= nil
379
383
  end
384
+
385
+ # Sets the sorting parameters for enumeration over the SearchResults items in the collection.
386
+ # #order takes multiple arguments, but each even numbered argument must be either :asc or :desc
387
+ # When given a single argument #order defaults to :asc
388
+ # @example
389
+ # @app[:items].search("location: Portland").order(:name, :asc, :rank, :desc, :created_at)
390
+ # the :created_at parameter will default to :asc
391
+ def order(*args)
392
+ sort = args.each_slice(2).map {|field, dir| dir ||= :asc; "#{field}:#{dir}" }.join(",")
393
+ self.class.new(collection, query, sort)
394
+ end
380
395
 
381
396
  include Enumerable
382
397
 
@@ -393,6 +408,7 @@ module Orchestrate
393
408
  def each
394
409
  params = {limit:limit}
395
410
  params[:offset] = offset if offset
411
+ params[:sort] = sort if sort
396
412
  @response ||= collection.perform(:search, query, params)
397
413
  return enum_for(:each) unless block_given?
398
414
  raise ResultsNotReady.new if collection.app.inside_parallel?
@@ -1,4 +1,4 @@
1
1
  module Orchestrate
2
2
  # @return [String] The version number of the Orchestrate Gem
3
- VERSION = "0.9.1"
3
+ VERSION = "0.9.2"
4
4
  end
@@ -19,6 +19,24 @@ class ApplicationTest < MiniTest::Unit::TestCase
19
19
  assert pinged, "API wasn't pinged"
20
20
  end
21
21
 
22
+ def test_instantianes_with_api_key_and_host
23
+ stubs = Faraday::Adapter::Test::Stubs.new
24
+ pinged = false
25
+ stubs.head('/v0') do |env|
26
+ pinged = true
27
+ [200, response_headers, '']
28
+ end
29
+ host = "https://example.com"
30
+ app = Orchestrate::Application.new("api_key", host) do |conn|
31
+ conn.adapter :test, stubs
32
+ end
33
+
34
+ assert_equal host, app.host
35
+ assert_equal "api_key", app.api_key
36
+ assert_kind_of Orchestrate::Client, app.client
37
+ assert pinged, "API wasn't pinged"
38
+ end
39
+
22
40
  def test_instantiates_with_client
23
41
  client, stubs = make_client_and_artifacts
24
42
  pinged = false
@@ -33,6 +51,21 @@ class ApplicationTest < MiniTest::Unit::TestCase
33
51
  assert pinged, "API wasn't pinged"
34
52
  end
35
53
 
54
+ def test_instantiates_with_client_and_host
55
+ client, stubs = make_client_and_artifacts
56
+ pinged = false
57
+ stubs.head('/v0') do |env|
58
+ pinged = true
59
+ [ 200, response_headers, '' ]
60
+ end
61
+ host = 'https://example.com'
62
+ app = Orchestrate::Application.new(client, host)
63
+ assert_equal client.host, app.host
64
+ assert_equal client.api_key, app.api_key
65
+ assert_equal client, app.client
66
+ assert pinged, "API wasn't pinged"
67
+ end
68
+
36
69
  def test_collection_accessor
37
70
  app, stubs = make_application
38
71
  users = app[:users]
@@ -3,6 +3,9 @@ require "test_helper"
3
3
  class ClientTest < MiniTest::Unit::TestCase
4
4
 
5
5
  def test_initialization
6
+ host = 'https://example.com'
7
+ client = Orchestrate::Client.new('8c3', host)
8
+ assert_equal host, client.host
6
9
  client = Orchestrate::Client.new('8c3')
7
10
  assert_equal '8c3', client.api_key
8
11
  end
@@ -0,0 +1,81 @@
1
+ require "test_helper"
2
+
3
+ class CollectionSortingTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ @app, @stubs = make_application({parallel:true})
6
+ @items = @app[:items]
7
+
8
+ @query = "foo"
9
+ @limit = 100
10
+ @total = 110
11
+
12
+ @make_listing = lambda{|i| make_kv_listing(:items, key: "item-#{i}", reftime: nil, score: @total-i/@total*5.0, rank: @total-i/@total*2.0 )}
13
+ @handle_offset = lambda do |offset|
14
+ case offset
15
+ when nil
16
+ { "results" => 100.times.map{|i| @make_listing.call(i)}, "count" => 100, "total_count" => @total,
17
+ "next" => "/v0/items?query=foo&offset=100&limit=100"}
18
+ when "100"
19
+ { "results" => 10.times.map{|i| @make_listing.call(i+100)}, "count" => 10, "total_count" => @total }
20
+ else
21
+ raise ArgumentError.new("unexpected offset: #{env.params['offset']}")
22
+ end
23
+ end
24
+
25
+ @called = false
26
+ @stubs.get("/v0/items") do |env|
27
+ @called = true
28
+ assert_equal @query, env.params['query']
29
+ assert_equal @limit, env.params['limit'].to_i
30
+ body = @handle_offset.call(env.params['offset'])
31
+ [ 200, response_headers, body.to_json ]
32
+ end
33
+ end
34
+
35
+ def test_basic_sort_ascending
36
+ results = @items.search("foo").order(:score, :asc).map{|i| i }
37
+ assert_equal 110, results.length
38
+ results.each_with_index do |item, idx|
39
+ assert_in_delta (@total-idx/@total * 5.0), item[0], 0.005
40
+ assert_equal "item-#{idx}", item[1].key
41
+ assert_equal @total-idx/@total*5.0, item["score".to_i]
42
+ assert_nil item[1].reftime
43
+ end
44
+ end
45
+
46
+ def test_basic_sort_descending
47
+ results = @items.search("foo").order(:score, :desc).map{|i| i }
48
+ assert_equal 110, results.length
49
+ results.each_with_index do |item, idx|
50
+ assert_in_delta (@total-idx/@total * 5.0), item[0], 0.005
51
+ assert_equal "item-#{idx}", item[1].key
52
+ assert_equal @total-idx/@total*5.0, item["score".to_i]
53
+ assert_nil item[1].reftime
54
+ end
55
+ end
56
+
57
+ def test_basic_multiple_fields_sort_ascending
58
+ results = @items.search("foo").order(:score, :asc, :rank, :asc).map{|i| i }
59
+ assert_equal 110, results.length
60
+ results.each_with_index do |item, idx|
61
+ assert_in_delta (@total-idx/@total * 5.0), item[0], 0.005
62
+ assert_equal "item-#{idx}", item[1].key
63
+ assert_equal @total-idx/@total*5.0, item["score".to_i]
64
+ assert_equal @total-idx/@total*2.0, item["rank".to_i]
65
+ assert_nil item[1].reftime
66
+ end
67
+ end
68
+
69
+ def test_basic_multiple_fields_sort_descending
70
+ results = @items.search("foo").order(:score, :asc, :rank, :desc).map{|i| i }
71
+ assert_equal 110, results.length
72
+ results.each_with_index do |item, idx|
73
+ assert_in_delta (@total-idx/@total * 5.0), item[0], 0.005
74
+ assert_equal "item-#{idx}", item[1].key
75
+ assert_equal @total-idx/@total*5.0, item["score".to_i]
76
+ assert_equal @total-idx/@total*2.0, item["rank".to_i]
77
+ assert_nil item[1].reftime
78
+ end
79
+ end
80
+
81
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orchestrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Lyon
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-10-08 00:00:00.000000000 Z
13
+ date: 2014-11-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: faraday
@@ -152,6 +152,7 @@ files:
152
152
  - test/orchestrate/collection_enumeration_test.rb
153
153
  - test/orchestrate/collection_kv_accessors_test.rb
154
154
  - test/orchestrate/collection_searching_test.rb
155
+ - test/orchestrate/collection_sorting_test.rb
155
156
  - test/orchestrate/collection_test.rb
156
157
  - test/orchestrate/event_enumeration_test.rb
157
158
  - test/orchestrate/event_test.rb
@@ -196,6 +197,7 @@ test_files:
196
197
  - test/orchestrate/collection_enumeration_test.rb
197
198
  - test/orchestrate/collection_kv_accessors_test.rb
198
199
  - test/orchestrate/collection_searching_test.rb
200
+ - test/orchestrate/collection_sorting_test.rb
199
201
  - test/orchestrate/collection_test.rb
200
202
  - test/orchestrate/event_enumeration_test.rb
201
203
  - test/orchestrate/event_test.rb