riddle 1.4.0 → 1.5.0

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