riddle 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. data/.gitignore +6 -0
  2. data/.travis.yml +16 -0
  3. data/Gemfile +6 -0
  4. data/HISTORY +45 -0
  5. data/LICENCE +20 -0
  6. data/README.textile +5 -3
  7. data/Rakefile +23 -0
  8. data/lib/riddle.rb +1 -0
  9. data/lib/riddle/0.9.9/configuration/searchd.rb +10 -8
  10. data/lib/riddle/auto_version.rb +2 -2
  11. data/lib/riddle/client.rb +117 -118
  12. data/lib/riddle/configuration.rb +6 -6
  13. data/lib/riddle/configuration/distributed_index.rb +16 -16
  14. data/lib/riddle/configuration/sql_source.rb +5 -5
  15. data/lib/riddle/controller.rb +28 -25
  16. data/lib/riddle/query.rb +31 -20
  17. data/lib/riddle/query/select.rb +69 -8
  18. data/lib/riddle/version.rb +3 -0
  19. data/riddle.gemspec +25 -0
  20. data/spec/fixtures/.gitignore +2 -0
  21. data/spec/fixtures/data/0.9.9/anchor.bin +0 -0
  22. data/spec/fixtures/data/0.9.9/any.bin +0 -0
  23. data/spec/fixtures/data/0.9.9/boolean.bin +0 -0
  24. data/spec/fixtures/data/0.9.9/comment.bin +0 -0
  25. data/spec/fixtures/data/0.9.9/distinct.bin +0 -0
  26. data/spec/fixtures/data/0.9.9/field_weights.bin +0 -0
  27. data/spec/fixtures/data/0.9.9/filter.bin +0 -0
  28. data/spec/fixtures/data/0.9.9/filter_array.bin +0 -0
  29. data/spec/fixtures/data/0.9.9/filter_array_exclude.bin +0 -0
  30. data/spec/fixtures/data/0.9.9/filter_boolean.bin +0 -0
  31. data/spec/fixtures/data/0.9.9/filter_floats.bin +0 -0
  32. data/spec/fixtures/data/0.9.9/filter_floats_exclude.bin +0 -0
  33. data/spec/fixtures/data/0.9.9/filter_range.bin +0 -0
  34. data/spec/fixtures/data/0.9.9/filter_range_exclude.bin +0 -0
  35. data/spec/fixtures/data/0.9.9/group.bin +0 -0
  36. data/spec/fixtures/data/0.9.9/index.bin +0 -0
  37. data/spec/fixtures/data/0.9.9/index_weights.bin +0 -0
  38. data/spec/fixtures/data/0.9.9/keywords_with_hits.bin +0 -0
  39. data/spec/fixtures/data/0.9.9/keywords_without_hits.bin +0 -0
  40. data/spec/fixtures/data/0.9.9/overrides.bin +0 -0
  41. data/spec/fixtures/data/0.9.9/phrase.bin +0 -0
  42. data/spec/fixtures/data/0.9.9/rank_mode.bin +0 -0
  43. data/spec/fixtures/data/0.9.9/select.bin +0 -0
  44. data/spec/fixtures/data/0.9.9/simple.bin +0 -0
  45. data/spec/fixtures/data/0.9.9/sort.bin +0 -0
  46. data/spec/fixtures/data/0.9.9/update_simple.bin +0 -0
  47. data/spec/fixtures/data/0.9.9/weights.bin +0 -0
  48. data/spec/fixtures/data/1.10/anchor.bin +0 -0
  49. data/spec/fixtures/data/1.10/any.bin +0 -0
  50. data/spec/fixtures/data/1.10/boolean.bin +0 -0
  51. data/spec/fixtures/data/1.10/comment.bin +0 -0
  52. data/spec/fixtures/data/1.10/distinct.bin +0 -0
  53. data/spec/fixtures/data/1.10/field_weights.bin +0 -0
  54. data/spec/fixtures/data/1.10/filter.bin +0 -0
  55. data/spec/fixtures/data/1.10/filter_array.bin +0 -0
  56. data/spec/fixtures/data/1.10/filter_array_exclude.bin +0 -0
  57. data/spec/fixtures/data/1.10/filter_boolean.bin +0 -0
  58. data/spec/fixtures/data/1.10/filter_floats.bin +0 -0
  59. data/spec/fixtures/data/1.10/filter_floats_exclude.bin +0 -0
  60. data/spec/fixtures/data/1.10/filter_range.bin +0 -0
  61. data/spec/fixtures/data/1.10/filter_range_exclude.bin +0 -0
  62. data/spec/fixtures/data/1.10/group.bin +0 -0
  63. data/spec/fixtures/data/1.10/index.bin +0 -0
  64. data/spec/fixtures/data/1.10/index_weights.bin +0 -0
  65. data/spec/fixtures/data/1.10/keywords_with_hits.bin +0 -0
  66. data/spec/fixtures/data/1.10/keywords_without_hits.bin +0 -0
  67. data/spec/fixtures/data/1.10/overrides.bin +0 -0
  68. data/spec/fixtures/data/1.10/phrase.bin +0 -0
  69. data/spec/fixtures/data/1.10/rank_mode.bin +0 -0
  70. data/spec/fixtures/data/1.10/select.bin +0 -0
  71. data/spec/fixtures/data/1.10/simple.bin +0 -0
  72. data/spec/fixtures/data/1.10/sort.bin +0 -0
  73. data/spec/fixtures/data/1.10/update_simple.bin +0 -0
  74. data/spec/fixtures/data/1.10/weights.bin +0 -0
  75. data/spec/fixtures/data/2.0.1/anchor.bin +0 -0
  76. data/spec/fixtures/data/2.0.1/any.bin +0 -0
  77. data/spec/fixtures/data/2.0.1/boolean.bin +0 -0
  78. data/spec/fixtures/data/2.0.1/comment.bin +0 -0
  79. data/spec/fixtures/data/2.0.1/distinct.bin +0 -0
  80. data/spec/fixtures/data/2.0.1/field_weights.bin +0 -0
  81. data/spec/fixtures/data/2.0.1/filter.bin +0 -0
  82. data/spec/fixtures/data/2.0.1/filter_array.bin +0 -0
  83. data/spec/fixtures/data/2.0.1/filter_array_exclude.bin +0 -0
  84. data/spec/fixtures/data/2.0.1/filter_boolean.bin +0 -0
  85. data/spec/fixtures/data/2.0.1/filter_floats.bin +0 -0
  86. data/spec/fixtures/data/2.0.1/filter_floats_exclude.bin +0 -0
  87. data/spec/fixtures/data/2.0.1/filter_range.bin +0 -0
  88. data/spec/fixtures/data/2.0.1/filter_range_exclude.bin +0 -0
  89. data/spec/fixtures/data/2.0.1/group.bin +0 -0
  90. data/spec/fixtures/data/2.0.1/index.bin +0 -0
  91. data/spec/fixtures/data/2.0.1/index_weights.bin +0 -0
  92. data/spec/fixtures/data/2.0.1/keywords_with_hits.bin +0 -0
  93. data/spec/fixtures/data/2.0.1/keywords_without_hits.bin +0 -0
  94. data/spec/fixtures/data/2.0.1/overrides.bin +0 -0
  95. data/spec/fixtures/data/2.0.1/phrase.bin +0 -0
  96. data/spec/fixtures/data/2.0.1/rank_mode.bin +0 -0
  97. data/spec/fixtures/data/2.0.1/select.bin +0 -0
  98. data/spec/fixtures/data/2.0.1/simple.bin +0 -0
  99. data/spec/fixtures/data/2.0.1/sort.bin +0 -0
  100. data/spec/fixtures/data/2.0.1/update_simple.bin +0 -0
  101. data/spec/fixtures/data/2.0.1/weights.bin +0 -0
  102. data/spec/fixtures/data_generator.0.9.8.php +208 -0
  103. data/spec/fixtures/data_generator.0.9.9.php +5 -0
  104. data/spec/fixtures/data_generator.1.10.php +5 -0
  105. data/spec/fixtures/data_generator.2.0.1.php +5 -0
  106. data/spec/fixtures/data_generator.php +223 -0
  107. data/spec/fixtures/sphinxapi.0.9.8.php +1228 -0
  108. data/spec/fixtures/sphinxapi.0.9.9.php +1646 -0
  109. data/spec/fixtures/sphinxapi.1.10.php +1728 -0
  110. data/spec/fixtures/sphinxapi.2.0.1.php +1731 -0
  111. data/spec/fixtures/sql/conf.example.yml +3 -0
  112. data/spec/fixtures/sql/data.sql +25000 -0
  113. data/spec/fixtures/sql/data.tsv +25000 -0
  114. data/spec/fixtures/sql/structure.sql +16 -0
  115. data/spec/functional/connection_spec.rb +10 -12
  116. data/spec/functional/excerpt_spec.rb +1 -1
  117. data/spec/functional/keywords_spec.rb +1 -1
  118. data/spec/functional/persistance_spec.rb +1 -1
  119. data/spec/functional/search_spec.rb +1 -1
  120. data/spec/functional/status_spec.rb +1 -1
  121. data/spec/functional/update_spec.rb +1 -1
  122. data/spec/riddle/auto_version_spec.rb +18 -10
  123. data/spec/riddle/query/select_spec.rb +78 -14
  124. data/spec/riddle/query_spec.rb +5 -3
  125. data/spec/spec_helper.rb +13 -15
  126. data/spec/support/binary_fixtures.rb +18 -0
  127. data/spec/support/sphinx.rb +135 -0
  128. data/spec/unit/client_spec.rb +150 -142
  129. data/spec/unit/configuration/distributed_index_spec.rb +15 -15
  130. data/spec/unit/configuration/searchd_spec.rb +28 -3
  131. data/spec/unit/configuration_spec.rb +6 -6
  132. metadata +254 -68
  133. data/spec/sphinx_helper.rb +0 -96
@@ -0,0 +1,16 @@
1
+ DROP TABLE IF EXISTS `people`;
2
+
3
+ CREATE TABLE `people` (
4
+ `id` int(11) NOT NULL auto_increment,
5
+ `first_name` varchar(50) NOT NULL,
6
+ `middle_initial` varchar(10) NOT NULL,
7
+ `last_name` varchar(50) NOT NULL,
8
+ `gender` varchar(10) NOT NULL,
9
+ `street_address` varchar(200) NOT NULL,
10
+ `city` varchar(100) NOT NULL,
11
+ `state` varchar(100) NOT NULL,
12
+ `postcode` varchar(10) NOT NULL,
13
+ `email` varchar(100) NOT NULL,
14
+ `birthday` datetime NOT NULL,
15
+ PRIMARY KEY (`id`)
16
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8
@@ -2,10 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  class RiddleSpecConnectionProcError < StandardError; end
4
4
 
5
- describe "Sphinx Client" do
6
- before :each do
7
- @client = Riddle::Client.new("localhost", 9313)
8
- end
5
+ describe 'Sphinx Client', :live => true do
6
+ let(:client) { Riddle::Client.new 'localhost', 9313 }
9
7
 
10
8
  after :each do
11
9
  Riddle::Client.connection = nil
@@ -16,31 +14,31 @@ describe "Sphinx Client" do
16
14
  Riddle::Client.connection = lambda { |client|
17
15
  TCPSocket.new(client.server, client.port)
18
16
  }
19
- @client.query("smith").should be_kind_of(Hash)
17
+ client.query('smith').should be_kind_of(Hash)
20
18
  end
21
19
 
22
20
  it "should fail with errors from the given block" do
23
21
  Riddle::Client.connection = lambda { |client|
24
22
  raise RiddleSpecConnectionProcError
25
23
  }
26
- lambda { @client.query("smith") }.
24
+ lambda { client.query('smith') }.
27
25
  should raise_error(RiddleSpecConnectionProcError)
28
26
  end
29
27
  end
30
28
 
31
29
  describe '#connection' do
32
30
  it "use the given block" do
33
- @client.connection = lambda { |client|
31
+ client.connection = lambda { |client|
34
32
  TCPSocket.new(client.server, client.port)
35
33
  }
36
- @client.query("smith").should be_kind_of(Hash)
34
+ client.query('smith').should be_kind_of(Hash)
37
35
  end
38
36
 
39
37
  it "should fail with errors from the given block" do
40
- @client.connection = lambda { |client|
38
+ client.connection = lambda { |client|
41
39
  raise RiddleSpecConnectionProcError
42
40
  }
43
- lambda { @client.query("smith") }.
41
+ lambda { client.query('smith') }.
44
42
  should raise_error(RiddleSpecConnectionProcError)
45
43
  end
46
44
 
@@ -48,11 +46,11 @@ describe "Sphinx Client" do
48
46
  Riddle::Client.connection = lambda { |client|
49
47
  raise RiddleSpecConnectionProcError
50
48
  }
51
- @client.connection = lambda { |client|
49
+ client.connection = lambda { |client|
52
50
  TCPSocket.new(client.server, client.port)
53
51
  }
54
52
 
55
- lambda { @client.query("smith") }.should_not raise_error
53
+ lambda { client.query('smith') }.should_not raise_error
56
54
  end
57
55
  end
58
56
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Sphinx Excepts" do
3
+ describe "Sphinx Excepts", :live => true do
4
4
  before :each do
5
5
  @client = Riddle::Client.new("localhost", 9313)
6
6
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Sphinx Keywords" do
3
+ describe "Sphinx Keywords", :live => true do
4
4
  before :each do
5
5
  @client = Riddle::Client.new("localhost", 9313)
6
6
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Sphinx Persistance Connection" do
3
+ describe "Sphinx Persistance Connection", :live => true do
4
4
  before :each do
5
5
  @client = Riddle::Client.new("localhost", 9313)
6
6
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Sphinx Searches" do
3
+ describe "Sphinx Searches", :live => true do
4
4
  let(:client) { Riddle::Client.new 'localhost', 9313 }
5
5
 
6
6
  it "should return a single hash if a single query" do
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if Riddle.loaded_version == '0.9.9' || Riddle.loaded_version == '1.10'
4
- describe "Sphinx Status" do
4
+ describe "Sphinx Status", :live => true do
5
5
  before :each do
6
6
  @client = Riddle::Client.new("localhost", 9313)
7
7
  @status = @client.status
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Sphinx Updates" do
3
+ describe "Sphinx Updates", :live => true do
4
4
  before :each do
5
5
  @client = Riddle::Client.new("localhost", 9313)
6
6
  end
@@ -5,39 +5,47 @@ describe Riddle::AutoVersion do
5
5
  before :each do
6
6
  @controller = Riddle::Controller.new stub('configuration'), 'sphinx.conf'
7
7
  Riddle::Controller.stub!(:new => @controller)
8
+
9
+ unless ENV['SPHINX_VERSION'].nil?
10
+ @env_version, ENV['SPHINX_VERSION'] = ENV['SPHINX_VERSION'].dup, nil
11
+ end
12
+ end
13
+
14
+ after :each do
15
+ ENV['SPHINX_VERSION'] = @env_version unless @env_version.nil?
8
16
  end
9
-
17
+
10
18
  it "should require 0.9.8 if that is the known version" do
11
19
  Riddle::AutoVersion.should_receive(:require).with('riddle/0.9.8')
12
-
20
+
13
21
  @controller.stub!(:sphinx_version => '0.9.8')
14
22
  Riddle::AutoVersion.configure
15
23
  end
16
-
24
+
17
25
  it "should require 0.9.9 if that is the known version" do
18
26
  Riddle::AutoVersion.should_receive(:require).with('riddle/0.9.9')
19
-
27
+
20
28
  @controller.stub!(:sphinx_version => '0.9.9')
21
29
  Riddle::AutoVersion.configure
22
30
  end
23
-
31
+
24
32
  it "should require 1.10 if that is the known version" do
25
33
  Riddle::AutoVersion.should_receive(:require).with('riddle/1.10')
26
-
34
+
27
35
  @controller.stub!(:sphinx_version => '1.10-beta')
28
36
  Riddle::AutoVersion.configure
29
37
  end
30
-
38
+
31
39
  it "should require 1.10 if using 1.10 with 64 bit IDs" do
32
40
  Riddle::AutoVersion.should_receive(:require).with('riddle/1.10')
33
-
41
+
34
42
  @controller.stub!(:sphinx_version => '1.10-id64-beta')
35
43
  Riddle::AutoVersion.configure
36
44
  end
37
-
45
+
38
46
  it "should require 2.0.1 if that is the known version" do
39
47
  Riddle::AutoVersion.should_receive(:require).with('riddle/2.0.1')
40
-
48
+
41
49
  @controller.stub!(:sphinx_version => '2.0.1-beta')
42
50
  Riddle::AutoVersion.configure
43
51
  end
@@ -2,63 +2,127 @@ require 'spec_helper'
2
2
 
3
3
  describe Riddle::Query::Select do
4
4
  let(:query) { Riddle::Query::Select.new }
5
-
5
+
6
6
  it 'handles basic queries on a specific index' do
7
7
  query.from('foo_core').to_sql.should == 'SELECT * FROM foo_core'
8
8
  end
9
-
9
+
10
10
  it 'handles queries on multiple indices' do
11
11
  query.from('foo_core').from('foo_delta').to_sql.
12
12
  should == 'SELECT * FROM foo_core, foo_delta'
13
13
  end
14
-
14
+
15
15
  it 'accepts multiple arguments for indices' do
16
16
  query.from('foo_core', 'foo_delta').to_sql.
17
17
  should == 'SELECT * FROM foo_core, foo_delta'
18
18
  end
19
-
19
+
20
+ it "handles custom select values" do
21
+ query.values('@weight').from('foo_core').to_sql.
22
+ should == 'SELECT *, @weight FROM foo_core'
23
+ end
24
+
20
25
  it 'handles basic queries with a search term' do
21
26
  query.from('foo_core').matching('foo').to_sql.
22
27
  should == "SELECT * FROM foo_core WHERE MATCH('foo')"
23
28
  end
24
-
29
+
25
30
  it 'handles filters with integers' do
26
31
  query.from('foo_core').matching('foo').where(:bar_id => 10).to_sql.
27
32
  should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bar_id = 10"
28
33
  end
29
-
34
+
35
+ it "handles exclusive filters with integers" do
36
+ query.from('foo_core').matching('foo').where_not(:bar_id => 10).to_sql.
37
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bar_id <> 10"
38
+ end
39
+
40
+ it "handles filters with true" do
41
+ query.from('foo_core').matching('foo').where(:bar => true).to_sql.
42
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bar = 1"
43
+ end
44
+
45
+ it "handles exclusive filters with true" do
46
+ query.from('foo_core').matching('foo').where_not(:bar => true).to_sql.
47
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bar <> 1"
48
+ end
49
+
50
+ it "handles filters with false" do
51
+ query.from('foo_core').matching('foo').where(:bar => false).to_sql.
52
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bar = 0"
53
+ end
54
+
55
+ it "handles exclusive filters with false" do
56
+ query.from('foo_core').matching('foo').where_not(:bar => false).to_sql.
57
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bar <> 0"
58
+ end
59
+
60
+ it "handles filters with arrays" do
61
+ query.from('foo_core').matching('foo').where(:bars => [1, 2]).to_sql.
62
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bars IN (1, 2)"
63
+ end
64
+
65
+ it "handles exclusive filters with arrays" do
66
+ query.from('foo_core').matching('foo').where_not(:bars => [1, 2]).to_sql.
67
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bars NOT IN (1, 2)"
68
+ end
69
+
70
+ it "handles filters with timestamps" do
71
+ time = Time.now
72
+ query.from('foo_core').matching('foo').where(:created_at => time).to_sql.
73
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND created_at = #{time.to_i}"
74
+ end
75
+
76
+ it "handles exclusive filters with timestamps" do
77
+ time = Time.now
78
+ query.from('foo_core').matching('foo').where_not(:created_at => time).
79
+ to_sql.should == "SELECT * FROM foo_core WHERE MATCH('foo') AND created_at <> #{time.to_i}"
80
+ end
81
+
82
+ it "handles filters with ranges" do
83
+ query.from('foo_core').matching('foo').where(:bar => 1..5).to_sql.
84
+ should == "SELECT * FROM foo_core WHERE MATCH('foo') AND bar BETWEEN 1 AND 5"
85
+ end
86
+
30
87
  it 'handles grouping' do
31
88
  query.from('foo_core').group_by('bar_id').to_sql.
32
89
  should == "SELECT * FROM foo_core GROUP BY bar_id"
33
90
  end
34
-
91
+
35
92
  it 'handles ordering' do
36
93
  query.from('foo_core').order_by('bar_id ASC').to_sql.
37
94
  should == 'SELECT * FROM foo_core ORDER BY bar_id ASC'
38
95
  end
39
-
96
+
40
97
  it 'handles group ordering' do
41
98
  query.from('foo_core').order_within_group_by('bar_id ASC').to_sql.
42
99
  should == 'SELECT * FROM foo_core WITHIN GROUP ORDER BY bar_id ASC'
43
100
  end
44
-
101
+
45
102
  it 'handles a limit' do
46
103
  query.from('foo_core').limit(10).to_sql.
47
104
  should == 'SELECT * FROM foo_core LIMIT 10'
48
105
  end
49
-
106
+
50
107
  it 'handles an offset' do
51
108
  query.from('foo_core').offset(20).to_sql.
52
109
  should == 'SELECT * FROM foo_core LIMIT 20, 20'
53
110
  end
54
-
111
+
55
112
  it 'handles an option' do
56
113
  query.from('foo_core').with_options(:bar => :baz).to_sql.
57
114
  should == 'SELECT * FROM foo_core OPTION bar=baz'
58
115
  end
59
-
116
+
60
117
  it 'handles multiple options' do
61
- query.from('foo_core').with_options(:bar => :baz, :qux => :quux).to_sql.
62
- should == 'SELECT * FROM foo_core OPTION bar=baz, qux=quux'
118
+ sql = query.from('foo_core').with_options(:bar => :baz, :qux => :quux).
119
+ to_sql
120
+ sql.should match(/OPTION .*bar=baz/)
121
+ sql.should match(/OPTION .*qux=quux/)
122
+ end
123
+
124
+ it "handles options of hashes" do
125
+ query.from('foo_core').with_options(:weights => {:foo => 5}).to_sql.
126
+ should == 'SELECT * FROM foo_core OPTION weights=(foo=5)'
63
127
  end
64
128
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Riddle::Query do
3
+ describe Riddle::Query, :live => true do
4
4
  describe '.connection' do
5
5
  let(:connection) { Riddle::Query.connection 'localhost', 9306 }
6
6
 
@@ -9,12 +9,14 @@ describe Riddle::Query do
9
9
  end
10
10
 
11
11
  it "should handle search requests" do
12
- connection.query(Riddle::Query.tables).first.should == {
12
+ connection.query(Riddle::Query.tables).to_a[0].should == {
13
13
  'Index' => 'people', 'Type' => 'local'
14
14
  }
15
15
  end
16
16
  end
17
-
17
+ end unless RUBY_PLATFORM == 'java' || Riddle.loaded_version.to_i < 2
18
+
19
+ describe Riddle::Query do
18
20
  describe '.set' do
19
21
  it 'handles a single value' do
20
22
  Riddle::Query.set('foo', 'bar').should == 'SET GLOBAL foo = bar'
@@ -4,33 +4,31 @@ require 'bundler'
4
4
  $:.unshift File.dirname(__FILE__) + '/../lib'
5
5
  $:.unshift File.dirname(__FILE__) + '/..'
6
6
 
7
+ Dir['spec/support/**/*.rb'].each { |f| require f }
8
+
7
9
  Bundler.require :default, :development
8
10
 
9
11
  require 'riddle'
10
- require 'sphinx_helper'
11
12
 
12
13
  RSpec.configure do |config|
13
- sphinx = SphinxHelper.new
14
+ config.include BinaryFixtures
15
+
16
+ sphinx = Sphinx.new
14
17
  sphinx.setup_mysql
15
18
  sphinx.generate_configuration
16
19
  sphinx.index
17
-
18
- config.before :all do
19
- `php -f spec/fixtures/data_generator.#{Riddle.loaded_version}.php`
20
- sphinx.start
20
+
21
+ BinaryFixtures.build_fixtures Riddle.loaded_version
22
+
23
+ config.before :all do |group|
24
+ sphinx.start if group.class.metadata[:live]
21
25
  end
22
-
23
- config.after :all do
24
- sphinx.stop
26
+
27
+ config.after :all do |group|
28
+ sphinx.stop if group.class.metadata[:live]
25
29
  end
26
30
 
27
31
  # enable filtering for examples
28
32
  config.filter_run :wip => true
29
33
  config.run_all_when_everything_filtered = true
30
34
  end
31
-
32
- def query_contents(key)
33
- contents = open("spec/fixtures/data/#{key.to_s}.bin") { |f| f.read }
34
- contents.respond_to?(:encoding) ?
35
- contents.force_encoding('ASCII-8BIT') : contents
36
- end
@@ -0,0 +1,18 @@
1
+ module BinaryFixtures
2
+ def self.build_fixtures(version = nil)
3
+ return if ENV['TRAVIS']
4
+
5
+ version ||= %w(0.9.9 1.10 2.0.1)
6
+ Array(version).each do |version|
7
+ FileUtils.mkdir_p "spec/fixtures/data/#{version}"
8
+ `php -f spec/fixtures/data_generator.#{version}.php`
9
+ end
10
+ end
11
+
12
+ def query_contents(key)
13
+ path = "spec/fixtures/data/#{Riddle.loaded_version}/#{key}.bin"
14
+ contents = open(path) { |f| f.read }
15
+ contents.respond_to?(:encoding) ?
16
+ contents.force_encoding('ASCII-8BIT') : contents
17
+ end
18
+ end
@@ -0,0 +1,135 @@
1
+ require 'erb'
2
+ require 'yaml'
3
+
4
+ if RUBY_PLATFORM == 'java'
5
+ require 'java'
6
+ require 'jdbc/mysql'
7
+ end
8
+
9
+ class Sphinx
10
+ attr_accessor :host, :username, :password
11
+
12
+ def initialize
13
+ self.host = 'localhost'
14
+ self.username = 'root'
15
+ self.password = ''
16
+
17
+ if File.exist?('spec/fixtures/sql/conf.yml')
18
+ config = YAML.load(File.open('spec/fixtures/sql/conf.yml'))
19
+ self.host = config['host']
20
+ self.username = config['username']
21
+ self.password = config['password']
22
+ end
23
+ end
24
+
25
+ def setup_mysql
26
+ return setup_mysql_on_jruby if RUBY_PLATFORM == 'java'
27
+
28
+ client = Mysql2::Client.new(
29
+ :host => host,
30
+ :username => username,
31
+ :password => password
32
+ )
33
+
34
+ databases = client.query('SHOW DATABASES', :as => :array).to_a.flatten
35
+ unless databases.include?('riddle')
36
+ client.query 'CREATE DATABASE riddle'
37
+ end
38
+
39
+ client.query 'USE riddle'
40
+
41
+ structure = File.open('spec/fixtures/sql/structure.sql') { |f| f.read }
42
+ structure.split(/;/).each { |sql| client.query sql }
43
+ client.query <<-SQL
44
+ LOAD DATA INFILE '#{fixtures_path}/sql/data.tsv' INTO TABLE
45
+ `riddle`.`people` FIELDS TERMINATED BY ',' ENCLOSED BY "'" (gender,
46
+ first_name, middle_initial, last_name, street_address, city, state,
47
+ postcode, email, birthday)
48
+ SQL
49
+
50
+ client.close
51
+ end
52
+
53
+ def setup_mysql_on_jruby
54
+ address = "jdbc:mysql://#{host}"
55
+ client = java.sql.DriverManager.getConnection(address, username, password)
56
+
57
+ set = client.createStatement.executeQuery('SHOW DATABASES')
58
+ databases = []
59
+ databases << set.getString(1) while set.next
60
+
61
+ unless databases.include?('riddle')
62
+ client.createStatement.execute 'CREATE DATABASE riddle'
63
+ end
64
+
65
+ client.createStatement.execute 'USE riddle'
66
+
67
+ structure = File.open('spec/fixtures/sql/structure.sql') { |f| f.read }
68
+ structure.split(/;/).each { |sql| client.createStatement.execute sql }
69
+ client.createStatement.execute <<-SQL
70
+ LOAD DATA INFILE '#{fixtures_path}/sql/data.tsv' INTO TABLE
71
+ `riddle`.`people` FIELDS TERMINATED BY ',' ENCLOSED BY "'" (gender,
72
+ first_name, middle_initial, last_name, street_address, city, state,
73
+ postcode, email, birthday)
74
+ SQL
75
+ end
76
+
77
+ def generate_configuration
78
+ template = File.open('spec/fixtures/sphinx/configuration.erb') { |f| f.read }
79
+ File.open('spec/fixtures/sphinx/spec.conf', 'w') { |f|
80
+ f.puts ERB.new(template).result(binding)
81
+ }
82
+ end
83
+
84
+ def index
85
+ cmd = "#{bin_path}indexer --config #{fixtures_path}/sphinx/spec.conf --all"
86
+ cmd << ' --rotate' if running?
87
+ `#{cmd}`
88
+ end
89
+
90
+ def start
91
+ return if running?
92
+
93
+ `#{bin_path}searchd --config #{fixtures_path}/sphinx/spec.conf`
94
+
95
+ sleep(1)
96
+
97
+ unless running?
98
+ puts 'Failed to start searchd daemon. Check fixtures/sphinx/searchd.log.'
99
+ end
100
+ end
101
+
102
+ def stop
103
+ return unless running?
104
+
105
+ stop_flag = '--stopwait'
106
+ stop_flag = '--stop' if Riddle.loaded_version.to_i < 1
107
+ `#{bin_path}searchd --config #{fixtures_path}/sphinx/spec.conf #{stop_flag}`
108
+ end
109
+
110
+ private
111
+
112
+ def pid
113
+ if File.exists?("#{fixtures_path}/sphinx/searchd.pid")
114
+ `cat #{fixtures_path}/sphinx/searchd.pid`[/\d+/]
115
+ else
116
+ nil
117
+ end
118
+ end
119
+
120
+ def running?
121
+ pid && `ps #{pid} | wc -l`.to_i > 1
122
+ end
123
+
124
+ def fixtures_path
125
+ File.expand_path File.join(File.dirname(__FILE__), '..', 'fixtures')
126
+ end
127
+
128
+ def bin_path
129
+ @bin_path ||= begin
130
+ path = (ENV['SPHINX_BIN'] || '').dup
131
+ path.insert -1, '/' if path.length > 0 && path[/\/$/].nil?
132
+ path
133
+ end
134
+ end
135
+ end