oedipus 0.0.15 → 0.0.16

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