oedipus 0.0.15 → 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,6 +12,8 @@ module Oedipus
12
12
  #
13
13
  # Currently this class wraps a native mysql extension.
14
14
  class Connection
15
+ attr_reader :options
16
+
15
17
  # Instantiate a new Connection to a SphinxQL host.
16
18
  #
17
19
  # @param [String] server
@@ -24,18 +26,21 @@ module Oedipus
24
26
  #
25
27
  # The underlying implementation uses a thread-safe connection pool.
26
28
  def initialize(options)
27
- options = options.kind_of?(String) ?
28
- Hash[ [:host, :port].zip(options.split(":")) ] :
29
- options
29
+ @options =
30
+ if options.kind_of?(String)
31
+ Hash[ [:host, :port].zip(options.split(":")) ]
32
+ else
33
+ options.dup
34
+ end.tap { |o| o[:port] = o[:port].to_i }
30
35
 
31
36
  @pool = Pool.new(
32
- host: options[:host],
33
- port: options[:port].to_i,
34
- size: options.fetch(:pool_size, 8),
37
+ host: @options[:host],
38
+ port: @options[:port],
39
+ size: @options.fetch(:pool_size, 8),
35
40
  ttl: 60
36
41
  )
37
42
 
38
- assert_valid_pool
43
+ assert_valid_pool unless @options[:verify] == false
39
44
  end
40
45
 
41
46
  # Acess a specific index for querying.
@@ -0,0 +1,125 @@
1
+ # encoding: utf-8
2
+
3
+ ##
4
+ # Oedipus Sphinx 2 Search.
5
+ # Copyright © 2012 Chris Corbyn.
6
+ #
7
+ # See LICENSE file for details.
8
+ ##
9
+
10
+ require "rspec/core"
11
+ require "tmpdir"
12
+
13
+ # RSpec shared context that may be included to provide a pre-defined index.
14
+ shared_context "oedipus posts_rt" do
15
+ def sphinx_indexes
16
+ <<-STR
17
+ index posts_rt
18
+ {
19
+ type = rt
20
+ path = #{data_dir}/posts_rt
21
+
22
+ rt_field = title
23
+ rt_field = body
24
+
25
+ rt_attr_uint = user_id
26
+ rt_attr_uint = views
27
+ rt_attr_string = state
28
+ }
29
+ STR
30
+ end
31
+ end
32
+
33
+ # RSpec shared context that may be included to start and stop sphinx between example groups.
34
+ shared_context "oedipus test rig" do
35
+ before(:all) do
36
+ write_sphinx_config
37
+ start_sphinx
38
+ end
39
+
40
+ after(:all) do
41
+ stop_sphinx
42
+ clean_data_dir
43
+ end
44
+
45
+ after(:each) { empty_indexes }
46
+
47
+ # It is intended that any or all of the following be overridden in tests.
48
+ def connection
49
+ @connection ||= Oedipus::Connection.new(host: "127.0.0.1", port: 9399, verify: false)
50
+ end
51
+
52
+ def data_dir
53
+ @data_dir ||= Dir.mktmpdir("oedipus")
54
+ end
55
+
56
+ def searchd
57
+ ENV["SEARCHD"] || "searchd"
58
+ end
59
+
60
+ def sphinx_indexes
61
+ <<-IDX.strip.gsub(/^ {4}/, "")
62
+ index test_rt {
63
+ type = rt
64
+ path = #{data_dir}/test_rt
65
+ rt_field = test"
66
+ }
67
+ IDX
68
+ end
69
+
70
+ def sphinx_conf
71
+ <<-CONF.strip.gsub(/^ {4}/, "")
72
+ ##
73
+ # This file is automatically generated during tests
74
+ ##
75
+
76
+ #{sphinx_indexes}
77
+
78
+ searchd
79
+ {
80
+ compat_sphinxql_magics = 0
81
+
82
+ max_matches = 2000
83
+ pid_file = #{data_dir}/searchd.pid
84
+ listen = #{connection.options[:host]}:#{connection.options[:port]}:mysql41
85
+ workers = threads
86
+ log = #{data_dir}/searchd.log
87
+ query_log = #{data_dir}/searchd.log
88
+ binlog_path = #{data_dir}
89
+ }
90
+ CONF
91
+ end
92
+
93
+ def write_sphinx_config
94
+ File.open("#{data_dir}/sphinx.conf", "w") do |f|
95
+ f << sphinx_conf
96
+ end
97
+ end
98
+
99
+ def start_sphinx
100
+ @pid = Process.spawn(
101
+ searchd, "--console", "-c", "#{data_dir}/sphinx.conf",
102
+ out: "#{data_dir}/searchd.out",
103
+ err: "#{data_dir}/searchd.err"
104
+ )
105
+ sleep 1
106
+ end
107
+
108
+ def stop_sphinx
109
+ Process.kill(:TERM, @pid) && Process.wait
110
+ end
111
+
112
+ def clean_data_dir
113
+ Dir["#{data_dir}/**/*"].each do |path|
114
+ File.delete(path)
115
+ end
116
+ end
117
+
118
+ def empty_indexes
119
+ connection.query("SHOW TABLES").each do |idx|
120
+ connection.query("SELECT id FROM #{idx['Index']}").each do |hash|
121
+ connection.execute("DELETE FROM #{idx['Index']} WHERE id = #{hash['id']}")
122
+ end
123
+ end
124
+ end
125
+ end
@@ -8,5 +8,5 @@
8
8
  ##
9
9
 
10
10
  module Oedipus
11
- VERSION = "0.0.15"
11
+ VERSION = "0.0.16"
12
12
  end
@@ -8,20 +8,11 @@
8
8
  ##
9
9
 
10
10
  require "spec_helper"
11
- require "oedipus/rspec/test_harness"
11
+ require "oedipus/rspec/test_rig"
12
12
 
13
13
  describe Oedipus::Connection::Registry do
14
- include Oedipus::RSpec::TestHarness
15
-
16
- before(:all) do
17
- set_data_dir File.expand_path("../../../data", __FILE__)
18
- set_searchd ENV["SEARCHD"]
19
- start_searchd
20
- end
21
-
22
- after(:all) { stop_searchd }
23
-
24
- before(:each) { empty_indexes }
14
+ include_context "oedipus test rig"
15
+ include_context "oedipus posts_rt"
25
16
 
26
17
  let(:registry) do
27
18
  Object.new.tap { |o| o.send(:extend, Oedipus::Connection::Registry) }
@@ -29,13 +20,13 @@ describe Oedipus::Connection::Registry do
29
20
 
30
21
  describe "#connect" do
31
22
  it "makes a new connection to a SphinxQL host" do
32
- registry.connect(searchd_host).should be_a_kind_of(Oedipus::Connection)
23
+ registry.connect(connection.options).should be_a_kind_of(Oedipus::Connection)
33
24
  end
34
25
  end
35
26
 
36
27
  describe "#connection" do
37
28
  context "without a name" do
38
- let(:conn) { registry.connect(searchd_host) }
29
+ let(:conn) { registry.connect(connection.options) }
39
30
 
40
31
  it "returns an existing connection" do
41
32
  conn.should equal registry.connection
@@ -43,7 +34,7 @@ describe Oedipus::Connection::Registry do
43
34
  end
44
35
 
45
36
  context "with a name" do
46
- let(:conn) { registry.connect(searchd_host, :bob) }
37
+ let(:conn) { registry.connect(connection.options, :bob) }
47
38
 
48
39
  it "returns the named connection" do
49
40
  conn.should equal registry.connection(:bob)
@@ -8,28 +8,21 @@
8
8
  ##
9
9
 
10
10
  require "spec_helper"
11
- require "oedipus/rspec/test_harness"
11
+ require "oedipus/rspec/test_rig"
12
12
 
13
13
  describe Oedipus::Connection do
14
- include Oedipus::RSpec::TestHarness
14
+ include_context "oedipus test rig"
15
+ include_context "oedipus posts_rt"
15
16
 
16
- before(:all) do
17
- set_data_dir File.expand_path("../../data", __FILE__)
18
- set_searchd ENV["SEARCHD"]
19
- start_searchd
20
- end
21
-
22
- after(:all) { stop_searchd }
23
-
24
- before(:each) { empty_indexes }
25
-
26
- let(:conn) { Oedipus::Connection.new(searchd_host) }
17
+ let(:conn) { Oedipus::Connection.new(connection.options) }
27
18
 
28
19
  describe "#initialize" do
29
20
  context "with a hosname:port string" do
30
21
  context "on successful connection" do
31
22
  it "returns the connection" do
32
- Oedipus::Connection.new(searchd_host.values.join(":")).should be_a_kind_of(Oedipus::Connection)
23
+ Oedipus::Connection.new(
24
+ "#{connection.options[:host]}:#{connection.options[:port]}"
25
+ ).should be_a_kind_of(Oedipus::Connection)
33
26
  end
34
27
  end
35
28
 
@@ -45,7 +38,7 @@ describe Oedipus::Connection do
45
38
  context "with an options Hash" do
46
39
  context "on successful connection" do
47
40
  it "returns the connection" do
48
- Oedipus::Connection.new(searchd_host).should be_a_kind_of(Oedipus::Connection)
41
+ Oedipus::Connection.new(connection.options).should be_a_kind_of(Oedipus::Connection)
49
42
  end
50
43
  end
51
44
 
@@ -8,22 +8,13 @@
8
8
  ##
9
9
 
10
10
  require "spec_helper"
11
- require "oedipus/rspec/test_harness"
11
+ require "oedipus/rspec/test_rig"
12
12
 
13
13
  describe Oedipus::Index do
14
- include Oedipus::RSpec::TestHarness
14
+ include_context "oedipus test rig"
15
+ include_context "oedipus posts_rt"
15
16
 
16
- before(:all) do
17
- set_data_dir File.expand_path("../../data", __FILE__)
18
- set_searchd ENV["SEARCHD"]
19
- start_searchd
20
- end
21
-
22
- after(:all) { stop_searchd }
23
-
24
- before(:each) { empty_indexes }
25
-
26
- let(:conn) { Oedipus::Connection.new(searchd_host) }
17
+ let(:conn) { connection }
27
18
  let(:index) { Oedipus::Index.new(:posts_rt, conn) }
28
19
 
29
20
  describe "#insert" do
@@ -340,7 +331,7 @@ describe Oedipus::Index do
340
331
  end
341
332
 
342
333
  context "with overriding overriding fulltext queries" do
343
- let(:results) do
334
+ let(:results) do # FIXME: Weird RSpec bug is not clearing the previous result, hence the ridiculous naming
344
335
  index.search(
345
336
  "badgers",
346
337
  facets: {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oedipus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.16
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-05-14 00:00:00.000000000 Z
12
+ date: 2012-05-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &20925980 !ruby/object:Gem::Requirement
16
+ requirement: &15535840 !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: :development
23
23
  prerelease: false
24
- version_requirements: *20925980
24
+ version_requirements: *15535840
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake-compiler
27
- requirement: &20925400 !ruby/object:Gem::Requirement
27
+ requirement: &15533700 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *20925400
35
+ version_requirements: *15533700
36
36
  description: ! "== Sphinx 2 Comes to Ruby\n\nOedipus brings full support for Sphinx
37
37
  2 to Ruby:\n\n - real-time indexes (insert, replace, update, delete)\n - faceted
38
38
  search (variations on a base query)\n - multi-queries (multiple queries executed
@@ -77,7 +77,7 @@ files:
77
77
  - lib/oedipus/connection_error.rb
78
78
  - lib/oedipus/index.rb
79
79
  - lib/oedipus/query_builder.rb
80
- - lib/oedipus/rspec/test_harness.rb
80
+ - lib/oedipus/rspec/test_rig.rb
81
81
  - lib/oedipus/version.rb
82
82
  - oedipus.gemspec
83
83
  - spec/data/.gitkeep
@@ -113,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
113
  version: '0'
114
114
  segments:
115
115
  - 0
116
- hash: 1288054359540287220
116
+ hash: 1033865904728202433
117
117
  required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  none: false
119
119
  requirements:
@@ -122,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  version: '0'
123
123
  segments:
124
124
  - 0
125
- hash: 1288054359540287220
125
+ hash: 1033865904728202433
126
126
  requirements: []
127
127
  rubyforge_project: oedipus
128
128
  rubygems_version: 1.8.11
@@ -1,152 +0,0 @@
1
- # encoding: utf-8
2
-
3
- ##
4
- # Oedipus Sphinx 2 Search.
5
- # Copyright © 2012 Chris Corbyn.
6
- #
7
- # See LICENSE file for details.
8
- ##
9
-
10
- module Oedipus
11
- module RSpec
12
- # Mixed into RSpec suites to manage starting/stopping Sphinx and writing indexes.
13
- module TestHarness
14
- # Set the path to the searchd executable.
15
- #
16
- # The version of Sphinx must be >= 2.0.2.
17
- #
18
- # @param [String] path
19
- # the absolute path to searchd
20
- def set_searchd(path)
21
- @searchd = path
22
- end
23
-
24
- # Set the path to a temporary directory for writing test data to.
25
- #
26
- # @param [String] path
27
- # the path to a writable directory whose contents may be completely deleted
28
- def set_data_dir(path)
29
- @data_dir = path
30
- end
31
-
32
- # Ensure that the temporary data directories exist and are clean.
33
- def prepare_data_dirs
34
- Dir.mkdir("#{data_dir}/index") unless Dir.exist?("#{data_dir}/index")
35
- Dir.mkdir("#{data_dir}/binlog") unless Dir.exist?("#{data_dir}/binlog")
36
-
37
- clean_data_dirs
38
- end
39
-
40
- def empty_indexes
41
- @conn ||= Oedipus::Connection.new(host: searchd_host[:host], port: searchd_host[:port])
42
-
43
- @conn.query("SHOW TABLES").each do |idx|
44
- @conn.query("SELECT id FROM #{idx['Index']}").each do |hash|
45
- @conn.execute("DELETE FROM #{idx['Index']} WHERE id = #{hash['id']}")
46
- end
47
- end
48
- end
49
-
50
- # Write the sphinx.conf file, using #index_definiton.
51
- #
52
- # Sphinx will listen on localhost port 9399.
53
- #
54
- # Any string returned from #index_definition will be used to define one or more indexes.
55
- def write_sphinx_conf
56
- File.open(searchd_config, "wb") do |f|
57
- f <<
58
- <<-CONF.gsub(/^ {10}/m, "")
59
- ##
60
- # This file is automatically generated during tests
61
- ##
62
-
63
- index posts_rt
64
- {
65
- type = rt
66
- path = #{data_dir}/index/posts_rt
67
-
68
- rt_field = title
69
- rt_field = body
70
-
71
- rt_attr_uint = user_id
72
- rt_attr_uint = views
73
- rt_attr_string = state
74
- }
75
-
76
- searchd
77
- {
78
- compat_sphinxql_magics = 0
79
-
80
- max_matches = 2000
81
- pid_file = #{data_dir}/searchd.pid
82
- listen = #{searchd_host[:host]}:#{searchd_host[:port]}:mysql41
83
- workers = threads
84
- log = #{data_dir}/searchd.log
85
- query_log = #{data_dir}/searchd.log
86
- binlog_path = #{data_dir}/binlog
87
- }
88
- CONF
89
- end
90
- end
91
-
92
- # Start the sphinx daemon in a child process and return the PID.
93
- #
94
- # Output is redirected to searchd.out and searchd.err in the data dir.
95
- def start_searchd
96
- prepare_data_dirs
97
- write_sphinx_conf
98
-
99
- @searchd_pid = Process.spawn(
100
- searchd, "--console", "-c", searchd_config,
101
- out: "#{data_dir}/searchd.out",
102
- err: "#{data_dir}/searchd.err"
103
- )
104
- sleep 1
105
- end
106
-
107
- # Stop an already running sphinx daemon and wait for it to shutdown.
108
- def stop_searchd
109
- Process.kill("TERM", @searchd_pid) && Process.wait
110
- end
111
-
112
- private
113
-
114
- def clean_data_dirs
115
- clean_files("#{data_dir}/index/**/*")
116
- clean_files("#{data_dir}/binlog/**/*")
117
- clean_files("#{data_dir}/searchd.pid")
118
- clean_files("#{data_dir}/searchd.out")
119
- clean_files("#{data_dir}/searchd.err")
120
- clean_files("#{data_dir}/sphinx.conf")
121
- end
122
-
123
- def searchd_host
124
- { host: "127.0.0.1", port: 9399 }
125
- end
126
-
127
- def searchd_config
128
- "#{data_dir}/sphinx.conf"
129
- end
130
-
131
- def clean_files(path)
132
- Dir[path].each { |f| File.delete(f) unless File.directory?(f) }
133
- end
134
-
135
- def data_dir
136
- unless @data_dir
137
- raise "Path to data directory unknown: call #set_data_dir during test setup"
138
- else
139
- @data_dir
140
- end
141
- end
142
-
143
- def searchd
144
- unless @searchd
145
- raise "Path to searchd unknown, perhaps you need to set the SEARCHD environment variable"
146
- else
147
- @searchd
148
- end
149
- end
150
- end
151
- end
152
- end