tire 0.5.0 → 0.5.1

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.
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