tire 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -24,37 +24,6 @@ namespace :test do
24
24
  end
25
25
  end
26
26
 
27
- # Generate documentation
28
- begin
29
- require 'rdoc'
30
- require 'rdoc/task'
31
- Rake::RDocTask.new do |rdoc|
32
- rdoc.rdoc_dir = 'rdoc'
33
- rdoc.title = "Tire"
34
- rdoc.rdoc_files.include('README.markdown')
35
- rdoc.rdoc_files.include('lib/**/*.rb')
36
- end
37
- rescue LoadError
38
- task :rdoc do
39
- abort "[!] RDoc gem is not available."
40
- end
41
- end
42
-
43
- # Generate coverage reports
44
- begin
45
- require 'rcov/rcovtask'
46
- Rcov::RcovTask.new do |test|
47
- test.libs << 'test'
48
- test.rcov_opts = ['--exclude', 'gems/*']
49
- test.pattern = 'test/**/*_test.rb'
50
- test.verbose = true
51
- end
52
- rescue LoadError
53
- task :rcov do
54
- abort "[!] RCov gem is not available."
55
- end
56
- end
57
-
58
27
  namespace :web do
59
28
 
60
29
  desc "Update the Github website"
data/lib/tire.rb CHANGED
@@ -11,6 +11,7 @@ require 'active_support/core_ext/hash/except.rb'
11
11
  # Ruby 1.8 compatibility
12
12
  require 'tire/rubyext/ruby_1_8' if defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
13
13
 
14
+ require 'tire/version'
14
15
  require 'tire/rubyext/hash'
15
16
  require 'tire/rubyext/symbol'
16
17
  require 'tire/utils'
data/lib/tire/index.rb CHANGED
@@ -90,16 +90,50 @@ module Tire
90
90
  logged([type, id].join('/'), curl)
91
91
  end
92
92
 
93
- def bulk_store(documents, options={})
93
+ # Performs a [multi-search](http://www.elasticsearch.org/guide/reference/api/bulk.html) request
94
+ #
95
+ # @myindex.bulk :index, [ {id: 1, title: 'One'}, { id: 2, title: 'Two', _version: 3 } ], refresh: true
96
+ #
97
+ # Pass the action (`index`, `create`, `delete`) as the first argument, the collection of documents as
98
+ # the second argument, and URL parameters as the last option.
99
+ #
100
+ # Any _meta_ information contained in documents (such as `_routing` or `_parent`) is extracted
101
+ # and added to the "header" line.
102
+ #
103
+ # Shortcut methods `bulk_store`, `bulk_delete` and `bulk_create` are available.
104
+ #
105
+ def bulk(action, documents, options={})
106
+ # TODO: A more Ruby-like DSL notation should be supported:
107
+ #
108
+ # Tire.index('myindex').bulk do
109
+ # create id: 1, title: 'bar', _routing: 'abc'
110
+ # delete id: 1
111
+ # # ...
112
+ # end
113
+ #
94
114
  payload = documents.map do |document|
95
115
  type = get_type_from_document(document, :escape => false) # Do not URL-escape the _type
96
116
  id = get_id_from_document(document)
97
117
 
98
118
  STDERR.puts "[ERROR] Document #{document.inspect} does not have ID" unless id
99
119
 
120
+ header = { action.to_sym => { :_index => name, :_type => type, :_id => id } }
121
+
122
+ if document.respond_to?(:to_hash) && hash = document.to_hash
123
+ meta = {}
124
+ meta[:_version] = hash.delete(:_version)
125
+ meta[:_routing] = hash.delete(:_routing)
126
+ meta[:_percolate] = hash.delete(:_percolate)
127
+ meta[:_parent] = hash.delete(:_parent)
128
+ meta[:_timestamp] = hash.delete(:_timestamp)
129
+ meta[:_ttl] = hash.delete(:_ttl)
130
+ meta = meta.reject { |name,value| !value || value.empty? }
131
+ header[action.to_sym].update(meta)
132
+ end
133
+
100
134
  output = []
101
- output << %Q|{"index":{"_index":"#{@name}","_type":"#{type}","_id":"#{id}"}}|
102
- output << convert_document_to_json(document)
135
+ output << MultiJson.encode(header)
136
+ output << convert_document_to_json(document) unless action.to_s == 'delete'
103
137
  output.join("\n")
104
138
  end
105
139
  payload << ""
@@ -108,7 +142,13 @@ module Tire
108
142
  count = 0
109
143
 
110
144
  begin
111
- @response = Configuration.client.post("#{url}/_bulk", payload.join("\n"))
145
+ params = {}
146
+ params[:consistency] = options.delete(:consistency)
147
+ params[:refresh] = options.delete(:refresh)
148
+ params = params.reject { |name,value| !value }
149
+ params_encoded = params.empty? ? '' : "?#{params.to_param}"
150
+
151
+ @response = Configuration.client.post("#{url}/_bulk#{params_encoded}", payload.join("\n"))
112
152
  raise RuntimeError, "#{@response.code} > #{@response.body}" if @response && @response.failure?
113
153
  @response
114
154
  rescue StandardError => error
@@ -123,8 +163,21 @@ module Tire
123
163
 
124
164
  ensure
125
165
  curl = %Q|curl -X POST "#{url}/_bulk" --data-binary '{... data omitted ...}'|
126
- logged('BULK', curl)
166
+ logged('_bulk', curl)
127
167
  end
168
+
169
+ end
170
+
171
+ def bulk_create(documents, options={})
172
+ bulk :create, documents, options
173
+ end
174
+
175
+ def bulk_store(documents, options={})
176
+ bulk :index, documents, options
177
+ end
178
+
179
+ def bulk_delete(documents, options={})
180
+ bulk :delete, documents, options
128
181
  end
129
182
 
130
183
  def import(klass_or_collection, options={})
data/lib/tire/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Tire
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
 
4
4
  CHANGELOG =<<-END
5
5
  IMPORTANT CHANGES LATELY:
@@ -29,5 +29,8 @@ module Tire
29
29
  * Added a `match` query type
30
30
  * Added support for multisearch (_msearch) and the `Tire.multi_search` DSL method
31
31
  * Added support for multi-search in the ActiveModel integration and in Tire::Model::Persistence
32
+ * Added support for create and delete actions for Index#bulk
33
+ * Added support for meta information (`_routing`, `_parent`, etc) in Index#bulk
34
+ * Added support for URL parameters (`refresh`, `consistency`) in Index#bulk
32
35
  END
33
36
  end
@@ -0,0 +1,81 @@
1
+ require 'test_helper'
2
+
3
+ module Tire
4
+
5
+ class BulkIntegrationTest < Test::Unit::TestCase
6
+ include Test::Integration
7
+
8
+ context "Bulk" do
9
+ setup do
10
+ @index = Tire.index('bulk-test') { delete; create }
11
+ @articles = [
12
+ { id: '1', type: 'article', title: 'one', tags: ['ruby'] },
13
+ { id: '2', type: 'article', title: 'two', tags: ['ruby', 'python'] },
14
+ { id: '3', type: 'article', title: 'three', tags: ['java'] }
15
+ ]
16
+ end
17
+
18
+ teardown do
19
+ @index.delete
20
+ Tire.index('bulk-test-fresh').delete
21
+ end
22
+
23
+ should "store a collection of documents and refresh the index" do
24
+ @index.bulk_store @articles, refresh: true
25
+ assert_equal 3, Tire.search('bulk-test/article').query { all }.results.size
26
+ end
27
+
28
+ should "extract the routing value from documents" do
29
+ @index.bulk_store [ { id: '1', title: 'A', _routing: 'a'}, { id: '2', title: 'B', _routing: 'b'} ]
30
+ @index.refresh
31
+
32
+ assert_equal 2, Tire.search('bulk-test') { query {all} }.results.size
33
+ assert_equal 1, Tire.search('bulk-test', routing: 'a') { query {all} }.results.size
34
+ assert_equal 1, Tire.search('bulk-test', routing: 'b') { query {all} }.results.size
35
+ end
36
+
37
+ should "delete documents in bulk" do
38
+ (1..10).to_a.each { |i| @index.store id: i }
39
+ @index.refresh
40
+ assert_equal 10, Tire.search('bulk-test') { query {all} }.results.size
41
+
42
+ documents = (1..10).to_a.map { |i| { id: i } }
43
+ @index.bulk_delete documents, refresh: true
44
+ assert_equal 0, Tire.search('bulk-test') { query {all} }.results.size
45
+ end
46
+
47
+ should "allow to feed search results to bulk API" do
48
+ (1..10).to_a.each { |i| @index.store id: i }
49
+ @index.refresh
50
+ assert_equal 10, Tire.search('bulk-test') { query {all} }.results.size
51
+
52
+ documents = Tire.search('bulk-test') { query {all} }.results.to_a
53
+
54
+ @index.bulk_delete documents, refresh: true
55
+ assert_equal 0, Tire.search('bulk-test') { query {all} }.results.size
56
+
57
+ Tire.index('bulk-test-fresh').bulk_create documents, refresh: true
58
+ assert_equal 10, Tire.search('bulk-test-fresh') { query {all} }.results.size
59
+ end
60
+
61
+ should "timeout when consistency factor is not met" do
62
+ # Tire.configure { logger STDERR, level: 'debug' }
63
+
64
+ Tire.index 'bulk-test' do
65
+ delete
66
+ create index: { number_of_shards: 1, number_of_replicas: 15 }
67
+ end
68
+
69
+ assert_raise Timeout::Error do
70
+ Timeout::timeout(3) do
71
+ Tire.index('bulk-test').bulk_store [ {id: '1', title: 'One' } ],
72
+ consistency: 'all',
73
+ raise: true
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -8,14 +8,6 @@ class MongoidArticle
8
8
  has_many :comments, :class_name => "MongoidComment", :foreign_key => "article_id"
9
9
  has_many :stats, :class_name => "MongoidStat", :foreign_key => "article_id"
10
10
 
11
- # def index
12
- # "KEEP OFF MY INDEX!!!"
13
- # end
14
- #
15
- # def self.settings
16
- # "KEEP OFF MY SETTINGS!!!"
17
- # end
18
-
19
11
  include Tire::Model::Search
20
12
  include Tire::Model::Callbacks
21
13
 
@@ -31,10 +23,6 @@ class MongoidArticle
31
23
  end
32
24
  end
33
25
 
34
- # tire.mapping do
35
- # indexes :title, :type => 'string', :boost => 10, :analyzer => 'snowball'
36
- # end
37
-
38
26
  def to_indexed_json
39
27
  {
40
28
  :title => title,
data/test/test_helper.rb CHANGED
@@ -4,7 +4,12 @@ require 'bundler/setup'
4
4
  require 'pathname'
5
5
  require 'test/unit'
6
6
 
7
- require 'yajl/json_gem'
7
+ if ENV['JSON_LIBRARY']
8
+ puts "Using '#{ENV['JSON_LIBRARY']}' JSON library"
9
+ require ENV['JSON_LIBRARY']
10
+ else
11
+ require 'yajl/json_gem'
12
+ end
8
13
  require 'sqlite3'
9
14
 
10
15
  require 'shoulda'
@@ -14,6 +19,11 @@ require 'mocha'
14
19
  require 'active_support/core_ext/hash/indifferent_access'
15
20
 
16
21
  require 'tire'
22
+ if ENV['CURB']
23
+ puts "Using 'curb' as the HTTP library"
24
+ require 'tire/http/clients/curb'
25
+ Tire.configure { client Tire::HTTP::Client::Curb }
26
+ end
17
27
 
18
28
  # Require basic model files
19
29
  #
@@ -370,7 +370,7 @@ module Tire
370
370
 
371
371
  should "allow to set routing" do
372
372
  Configuration.client.expects(:get).with("#{@index.url}/article/id-1?routing=foo").
373
- returns(mock_response('{"_id":"id-1"'))
373
+ returns(mock_response('{"_id":"id-1"}'))
374
374
  article = @index.retrieve :article, 'id-1', :routing => 'foo'
375
375
  end
376
376
 
@@ -378,7 +378,7 @@ module Tire
378
378
  Configuration.client.expects(:get).with do |url|
379
379
  assert url.include?('routing=foo'), url
380
380
  assert url.include?('fields=name'), url
381
- end.returns(mock_response('{"_id":"id-1"'))
381
+ end.returns(mock_response('{"_id":"id-1"}'))
382
382
 
383
383
  article = @index.retrieve :article, 'id-1', :routing => 'foo', :fields => 'name'
384
384
  end
@@ -386,7 +386,7 @@ module Tire
386
386
  should "allow to set preference" do
387
387
  Configuration.client.expects(:get).with do |url|
388
388
  assert url.include?('preference=foo'), url
389
- end.returns(mock_response('{"_id":"id-1"'))
389
+ end.returns(mock_response('{"_id":"id-1"}'))
390
390
 
391
391
  article = @index.retrieve :article, 'id-1', :preference => 'foo'
392
392
  end
@@ -490,56 +490,159 @@ module Tire
490
490
 
491
491
  end
492
492
 
493
- context "when storing in bulk" do
493
+ context "when performing a bulk api action" do
494
+ # Possible Bulk API actions are `index`, `create`, `delete`
495
+ #
494
496
  # The expected JSON looks like this:
495
497
  #
496
498
  # {"index":{"_index":"dummy","_type":"document","_id":"1"}}
497
499
  # {"id":"1","title":"One"}
498
- # {"index":{"_index":"dummy","_type":"document","_id":"2"}}
500
+ # {"create":{"_index":"dummy","_type":"document","_id":"2"}}
499
501
  # {"id":"2","title":"Two"}
502
+ # {"delete":{"_index":"dummy","_type":"document","_id":"2"}}
500
503
  #
501
504
  # See http://www.elasticsearch.org/guide/reference/api/bulk.html
502
505
 
503
- should "serialize Hashes" do
504
- Configuration.client.expects(:post).with do |url, json|
505
- url == "#{@index.url}/_bulk" &&
506
- json =~ /"_index":"dummy"/ &&
507
- json =~ /"_type":"document"/ &&
508
- json =~ /"_id":"1"/ &&
509
- json =~ /"_id":"2"/ &&
510
- json =~ /"id":"1"/ &&
511
- json =~ /"id":"2"/ &&
512
- json =~ /"title":"One"/ &&
513
- json =~ /"title":"Two"/
514
- end.returns(mock_response('{}'), 200)
506
+ should "serialize payload for index action" do
507
+ Configuration.client.
508
+ expects(:post).
509
+ with do |url, payload|
510
+ assert_equal "#{@index.url}/_bulk", url
511
+ assert_match /"index"/, payload
512
+ assert_match /"_index":"dummy"/, payload
513
+ assert_match /"_type":"document"/, payload
514
+ assert_match /"_id":"1"/, payload
515
+ assert_match /"_id":"2"/, payload
516
+ assert_match /"title":"One"/, payload
517
+ assert_match /"title":"Two"/, payload
518
+ end.
519
+ returns(mock_response('{}'), 200)
515
520
 
516
- @index.bulk_store [ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ]
521
+ @index.bulk :index, [ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ]
517
522
  end
518
523
 
519
- should "serialize ActiveModel instances" do
520
- Configuration.client.expects(:post).with do |url, json|
521
- url == "#{ActiveModelArticle.index.url}/_bulk" &&
522
- json =~ /"_index":"active_model_articles"/ &&
523
- json =~ /"_type":"active_model_article"/ &&
524
- json =~ /"_id":"1"/ &&
525
- json =~ /"_id":"2"/ &&
526
- json =~ /"title":"One"/ &&
527
- json =~ /"title":"Two"/
528
- end.returns(mock_response('{}', 200))
524
+ should "serialize payload for create action" do
525
+ Configuration.client.
526
+ expects(:post).
527
+ with do |url, payload|
528
+ assert_equal "#{@index.url}/_bulk", url
529
+ assert_match /"create"/, payload
530
+ assert_match /"_index":"dummy"/, payload
531
+ assert_match /"_type":"document"/, payload
532
+ assert_match /"_id":"1"/, payload
533
+ assert_match /"_id":"2"/, payload
534
+ assert_match /"title":"One"/, payload
535
+ assert_match /"title":"Two"/, payload
536
+ end.
537
+ returns(mock_response('{}'), 200)
538
+
539
+ @index.bulk :create, [ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ]
540
+ end
541
+
542
+ should "serialize payload for delete action" do
543
+ Configuration.client.
544
+ expects(:post).
545
+ with do |url, payload|
546
+ assert_equal "#{@index.url}/_bulk", url
547
+ assert_match /"delete"/, payload
548
+ assert_match /"_index":"dummy"/, payload
549
+ assert_match /"_type":"document"/, payload
550
+ assert_match /"_id":"1"/, payload
551
+ assert_match /"_id":"2"/, payload
552
+ assert ! payload.include?('"title"')
553
+ end.
554
+ returns(mock_response('{}'), 200)
555
+
556
+ @index.bulk :delete, [ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ]
557
+ end
558
+
559
+ should "serialize meta parameters such as routing into payload header" do
560
+ Configuration.client.
561
+ expects(:post).
562
+ with do |url, payload|
563
+ # print payload
564
+ lines = payload.split("\n")
565
+ assert_match /"_routing":"A"/, lines[0]
566
+ assert_match /"_routing":"B"/, lines[2]
567
+ assert_match /"_ttl":"1d"/, lines[2]
568
+ assert ! lines[4].include?('"_routing"')
569
+ end.
570
+ returns(mock_response('{}'), 200)
571
+
572
+ @index.bulk :index,
573
+ [
574
+ {:id => '1', :title => 'One', :_routing => 'A'},
575
+ {:id => '2', :title => 'Two', :_routing => 'B', :_ttl => '1d'},
576
+ {:id => '3', :title => 'Three'}
577
+ ]
578
+
579
+ end
580
+
581
+ should "pass URL parameters such as refresh or consistency" do
582
+ Configuration.client.
583
+ expects(:post).
584
+ with do |url, payload|
585
+ # p url
586
+ assert_match /\?consistency=one/, url
587
+ assert_match /&refresh=true/, url
588
+ end.
589
+ returns(mock_response('{}'), 200)
590
+
591
+ @index.bulk :index,
592
+ [ {:id => '1', :title => 'One' } ],
593
+ :consistency => 'one',
594
+ :refresh => true
595
+
596
+ end
597
+
598
+ should "serialize ActiveModel instances as payload" do
599
+ Configuration.client.
600
+ expects(:post).
601
+ with do |url, payload|
602
+ assert_equal "#{ActiveModelArticle.index.url}/_bulk", url
603
+ assert_match /"index"/, payload
604
+ assert_match /"_index":"active_model_articles"/, payload
605
+ assert_match /"_type":"active_model_article"/, payload
606
+ assert_match /"_id":"1"/, payload
607
+ assert_match /"_id":"2"/, payload
608
+ assert_match /"title":"One"/, payload
609
+ assert_match /"title":"Two"/, payload
610
+ end.
611
+ returns(mock_response('{}'), 200)
529
612
 
530
613
  one = ActiveModelArticle.new 'title' => 'One'; one.id = '1'
531
614
  two = ActiveModelArticle.new 'title' => 'Two'; two.id = '2'
532
615
 
533
- ActiveModelArticle.index.bulk_store [ one, two ]
616
+ ActiveModelArticle.index.bulk :index, [ one, two ]
534
617
  end
535
618
 
536
- context "namespaced models" do
619
+ should "extract meta information from document objects" do
620
+ Configuration.client.
621
+ expects(:post).
622
+ with do |url, payload|
623
+ print payload
624
+ lines = payload.split("\n")
625
+ assert_match /"_routing":"A"/, lines[0]
626
+ end.
627
+ returns(mock_response('{}'), 200)
628
+
629
+ class MyModel
630
+ def document_type; "my_model"; end
631
+ def to_hash; { :id => 1, :title => 'Foo', :_routing => 'A' }; end
632
+ def to_indexed_json; MultiJson.encode(to_hash); end
633
+ end
634
+
635
+ Tire.index('my_models').bulk_store [ MyModel.new ]
636
+ end
637
+
638
+ context "with namespaced models" do
639
+
537
640
  should "not URL-escape the document_type" do
538
- Configuration.client.expects(:post).with do |url, json|
539
- # puts url, json
540
- url == "#{Configuration.url}/my_namespace_my_models/_bulk" &&
541
- json =~ %r|"_index":"my_namespace_my_models"| &&
542
- json =~ %r|"_type":"my_namespace/my_model"|
641
+ Configuration.client.expects(:post).with do |url, payload|
642
+ # puts url, payload
643
+ assert_equal "#{Configuration.url}/my_namespace_my_models/_bulk", url
644
+ assert_match %r|"_index":"my_namespace_my_models"|, payload
645
+ assert_match %r|"_type":"my_namespace/my_model"|, payload
543
646
  end.returns(mock_response('{}', 200))
544
647
 
545
648
  module MyNamespace
@@ -549,35 +652,37 @@ module Tire
549
652
  end
550
653
  end
551
654
 
552
- Tire.index('my_namespace_my_models').bulk_store [ MyNamespace::MyModel.new ]
655
+ Tire.index('my_namespace_my_models').bulk :index, [ MyNamespace::MyModel.new ]
553
656
  end
554
657
  end
555
658
 
556
659
  should "try again when an exception occurs" do
557
660
  Configuration.client.expects(:post).returns(mock_response('Server error', 503)).at_least(2)
558
661
 
559
- assert !@index.bulk_store([ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ])
662
+ assert !@index.bulk(:index, [ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ])
560
663
  end
561
664
 
562
665
  should "try again and the raise when an exception occurs" do
563
666
  Configuration.client.expects(:post).returns(mock_response('Server error', 503)).at_least(2)
564
667
 
565
668
  assert_raise(RuntimeError) do
566
- @index.bulk_store([ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ], {:raise => true})
669
+ @index.bulk :index,
670
+ [ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ],
671
+ :raise => true
567
672
  end
568
673
  end
569
674
 
570
675
  should "try again when a connection error occurs" do
571
676
  Configuration.client.expects(:post).raises(Errno::ECONNREFUSED, "Connection refused - connect(2)").at_least(2)
572
677
 
573
- assert !@index.bulk_store([ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ])
678
+ assert !@index.bulk(:index, [ {:id => '1', :title => 'One'} ])
574
679
  end
575
680
 
576
- should "signal exceptions should not be caught" do
681
+ should "retry on SIGINT type of exceptions" do
577
682
  Configuration.client.expects(:post).raises(Interrupt, "abort then interrupt!")
578
683
 
579
684
  assert_raise Interrupt do
580
- @index.bulk_store([ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ])
685
+ @index.bulk :index, [ {:id => '1', :title => 'One'} ]
581
686
  end
582
687
  end
583
688
 
@@ -589,7 +694,7 @@ module Tire
589
694
  STDERR.expects(:puts).once
590
695
 
591
696
  documents = [ { :title => 'Bogus' }, { :title => 'Real', :id => 1 } ]
592
- ActiveModelArticle.index.bulk_store documents
697
+ ActiveModelArticle.index.bulk :index, documents
593
698
  end
594
699
 
595
700
  should "log the response code" do
@@ -600,7 +705,7 @@ module Tire
600
705
  status == 200
601
706
  end
602
707
 
603
- @index.bulk_store [ {:id => '1', :title => 'One'}, {:id => '2', :title => 'Two'} ]
708
+ @index.bulk :index, [ {:id => '1', :title => 'One'} ]
604
709
  end
605
710
 
606
711
  end
@@ -35,7 +35,7 @@ module Tire
35
35
  end
36
36
 
37
37
  should "have to_indexed_json method doing the same as to_json" do
38
- [{}, { 1 => 2 }, { 3 => 4, 5 => 6 }, { nil => [7,8,9] }].each do |h|
38
+ [{}, { :foo => 2 }, { :foo => 4, :bar => 6 }, { :foo => [7,8,9] }].each do |h|
39
39
  assert_equal MultiJson.decode(h.to_json), MultiJson.decode(h.to_indexed_json)
40
40
  end
41
41
  end
data/tire.gemspec CHANGED
@@ -38,21 +38,16 @@ Gem::Specification.new do |s|
38
38
  s.add_development_dependency "yajl-ruby", "~> 1.0"
39
39
  s.add_development_dependency "shoulda"
40
40
  s.add_development_dependency "mocha"
41
+ s.add_development_dependency "minitest", "~> 2.12"
41
42
  s.add_development_dependency "activerecord", ">= 3.0"
42
43
  s.add_development_dependency "sqlite3"
43
44
  s.add_development_dependency "mongoid", "~> 2.2"
44
45
  s.add_development_dependency "bson_ext"
45
46
  s.add_development_dependency "redis-persistence"
46
47
  s.add_development_dependency "curb"
47
- s.add_development_dependency "minitest"
48
+ s.add_development_dependency "oj"
48
49
  s.add_development_dependency "turn", "~> 0.9" if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
49
50
 
50
- # These gems are not needed for CI at <http://travis-ci.org/#!/karmi/tire>
51
- #
52
- unless ENV["CI"]
53
- s.add_development_dependency "rdoc"
54
- end
55
-
56
51
  s.description = <<-DESC
57
52
  Tire is a Ruby client for the ElasticSearch search engine/database.
58
53
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-08 00:00:00.000000000 Z
12
+ date: 2012-11-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70223214921740 !ruby/object:Gem::Requirement
16
+ requirement: &70241536312360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70223214921740
24
+ version_requirements: *70241536312360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rest-client
27
- requirement: &70223214920520 !ruby/object:Gem::Requirement
27
+ requirement: &70241536310740 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '1.6'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70223214920520
35
+ version_requirements: *70241536310740
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: multi_json
38
- requirement: &70223214919080 !ruby/object:Gem::Requirement
38
+ requirement: &70241536309980 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70223214919080
46
+ version_requirements: *70241536309980
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activemodel
49
- requirement: &70223214918580 !ruby/object:Gem::Requirement
49
+ requirement: &70241536309040 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '3.0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70223214918580
57
+ version_requirements: *70241536309040
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: hashr
60
- requirement: &70223214917880 !ruby/object:Gem::Requirement
60
+ requirement: &70241536306480 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.0.19
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70223214917880
68
+ version_requirements: *70241536306480
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
- requirement: &70223214917060 !ruby/object:Gem::Requirement
71
+ requirement: &70241536322700 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '1.0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70223214917060
79
+ version_requirements: *70241536322700
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: yajl-ruby
82
- requirement: &70223214915540 !ruby/object:Gem::Requirement
82
+ requirement: &70241536322000 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '1.0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70223214915540
90
+ version_requirements: *70241536322000
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: shoulda
93
- requirement: &70223214914780 !ruby/object:Gem::Requirement
93
+ requirement: &70241536321420 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70223214914780
101
+ version_requirements: *70241536321420
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: mocha
104
- requirement: &70223214930040 !ruby/object:Gem::Requirement
104
+ requirement: &70241536320760 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,21 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70223214930040
112
+ version_requirements: *70241536320760
113
+ - !ruby/object:Gem::Dependency
114
+ name: minitest
115
+ requirement: &70241536320180 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ~>
119
+ - !ruby/object:Gem::Version
120
+ version: '2.12'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70241536320180
113
124
  - !ruby/object:Gem::Dependency
114
125
  name: activerecord
115
- requirement: &70223214928700 !ruby/object:Gem::Requirement
126
+ requirement: &70241536319540 !ruby/object:Gem::Requirement
116
127
  none: false
117
128
  requirements:
118
129
  - - ! '>='
@@ -120,10 +131,10 @@ dependencies:
120
131
  version: '3.0'
121
132
  type: :development
122
133
  prerelease: false
123
- version_requirements: *70223214928700
134
+ version_requirements: *70241536319540
124
135
  - !ruby/object:Gem::Dependency
125
136
  name: sqlite3
126
- requirement: &70223214927400 !ruby/object:Gem::Requirement
137
+ requirement: &70241536319060 !ruby/object:Gem::Requirement
127
138
  none: false
128
139
  requirements:
129
140
  - - ! '>='
@@ -131,10 +142,10 @@ dependencies:
131
142
  version: '0'
132
143
  type: :development
133
144
  prerelease: false
134
- version_requirements: *70223214927400
145
+ version_requirements: *70241536319060
135
146
  - !ruby/object:Gem::Dependency
136
147
  name: mongoid
137
- requirement: &70223214926580 !ruby/object:Gem::Requirement
148
+ requirement: &70241536318220 !ruby/object:Gem::Requirement
138
149
  none: false
139
150
  requirements:
140
151
  - - ~>
@@ -142,10 +153,10 @@ dependencies:
142
153
  version: '2.2'
143
154
  type: :development
144
155
  prerelease: false
145
- version_requirements: *70223214926580
156
+ version_requirements: *70241536318220
146
157
  - !ruby/object:Gem::Dependency
147
158
  name: bson_ext
148
- requirement: &70223214925540 !ruby/object:Gem::Requirement
159
+ requirement: &70241536317400 !ruby/object:Gem::Requirement
149
160
  none: false
150
161
  requirements:
151
162
  - - ! '>='
@@ -153,10 +164,10 @@ dependencies:
153
164
  version: '0'
154
165
  type: :development
155
166
  prerelease: false
156
- version_requirements: *70223214925540
167
+ version_requirements: *70241536317400
157
168
  - !ruby/object:Gem::Dependency
158
169
  name: redis-persistence
159
- requirement: &70223214924920 !ruby/object:Gem::Requirement
170
+ requirement: &70241536316820 !ruby/object:Gem::Requirement
160
171
  none: false
161
172
  requirements:
162
173
  - - ! '>='
@@ -164,10 +175,10 @@ dependencies:
164
175
  version: '0'
165
176
  type: :development
166
177
  prerelease: false
167
- version_requirements: *70223214924920
178
+ version_requirements: *70241536316820
168
179
  - !ruby/object:Gem::Dependency
169
180
  name: curb
170
- requirement: &70223214923980 !ruby/object:Gem::Requirement
181
+ requirement: &70241536316100 !ruby/object:Gem::Requirement
171
182
  none: false
172
183
  requirements:
173
184
  - - ! '>='
@@ -175,10 +186,10 @@ dependencies:
175
186
  version: '0'
176
187
  type: :development
177
188
  prerelease: false
178
- version_requirements: *70223214923980
189
+ version_requirements: *70241536316100
179
190
  - !ruby/object:Gem::Dependency
180
- name: minitest
181
- requirement: &70223214923120 !ruby/object:Gem::Requirement
191
+ name: oj
192
+ requirement: &70241536339520 !ruby/object:Gem::Requirement
182
193
  none: false
183
194
  requirements:
184
195
  - - ! '>='
@@ -186,10 +197,10 @@ dependencies:
186
197
  version: '0'
187
198
  type: :development
188
199
  prerelease: false
189
- version_requirements: *70223214923120
200
+ version_requirements: *70241536339520
190
201
  - !ruby/object:Gem::Dependency
191
202
  name: turn
192
- requirement: &70223214922420 !ruby/object:Gem::Requirement
203
+ requirement: &70241536336900 !ruby/object:Gem::Requirement
193
204
  none: false
194
205
  requirements:
195
206
  - - ~>
@@ -197,18 +208,7 @@ dependencies:
197
208
  version: '0.9'
198
209
  type: :development
199
210
  prerelease: false
200
- version_requirements: *70223214922420
201
- - !ruby/object:Gem::Dependency
202
- name: rdoc
203
- requirement: &70223215704680 !ruby/object:Gem::Requirement
204
- none: false
205
- requirements:
206
- - - ! '>='
207
- - !ruby/object:Gem::Version
208
- version: '0'
209
- type: :development
210
- prerelease: false
211
- version_requirements: *70223215704680
211
+ version_requirements: *70241536336900
212
212
  description: ! " Tire is a Ruby client for the ElasticSearch search engine/database.\n\n
213
213
  \ It provides Ruby-like API for fluent communication with the ElasticSearch server\n
214
214
  \ and blends with ActiveModel class for convenient usage in Rails applications.\n\n
@@ -283,6 +283,7 @@ files:
283
283
  - test/integration/active_record_searchable_test.rb
284
284
  - test/integration/boolean_queries_test.rb
285
285
  - test/integration/boosting_queries_test.rb
286
+ - test/integration/bulk_test.rb
286
287
  - test/integration/count_test.rb
287
288
  - test/integration/custom_score_queries_test.rb
288
289
  - test/integration/dis_max_queries_test.rb
@@ -377,8 +378,10 @@ post_install_message: ! "=======================================================
377
378
  to Index#retrieve\n * Allow building the search request step-by-step in Tire's
378
379
  DSL [#496]\n * Added a `match` query type\n * Added support for multisearch (_msearch)
379
380
  and the `Tire.multi_search` DSL method\n * Added support for multi-search in the
380
- ActiveModel integration and in Tire::Model::Persistence\n\n See the full changelog
381
- at <http://github.com/karmi/tire/commits/v0.5.0>.\n\n--------------------------------------------------------------------------------\n"
381
+ ActiveModel integration and in Tire::Model::Persistence\n * Added support for create
382
+ and delete actions for Index#bulk\n * Added support for meta information (`_routing`,
383
+ `_parent`, etc) in Index#bulk\n * Added support for URL parameters (`refresh`,
384
+ `consistency`) in Index#bulk\n\n See the full changelog at <http://github.com/karmi/tire/commits/v0.5.1>.\n\n--------------------------------------------------------------------------------\n"
382
385
  rdoc_options:
383
386
  - --charset=UTF-8
384
387
  require_paths:
@@ -412,6 +415,7 @@ test_files:
412
415
  - test/integration/active_record_searchable_test.rb
413
416
  - test/integration/boolean_queries_test.rb
414
417
  - test/integration/boosting_queries_test.rb
418
+ - test/integration/bulk_test.rb
415
419
  - test/integration/count_test.rb
416
420
  - test/integration/custom_score_queries_test.rb
417
421
  - test/integration/dis_max_queries_test.rb