flying-sphinx 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY CHANGED
@@ -1,3 +1,7 @@
1
+ 0.6.0 - 31st July 2011
2
+ * Version in a separate file.
3
+ * Support for all file-based Sphinx settings: stopwords, wordforms, exceptions, and mysql ssl settings for SQL sources.
4
+
1
5
  0.5.2 - 28th July 2011
2
6
  * Log SSH exceptions during indexing (when we're being verbose).
3
7
  * This history file now exists (pre-populated).
@@ -1,7 +1,10 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'flying_sphinx/version'
4
+
2
5
  Gem::Specification.new do |s|
3
6
  s.name = 'flying-sphinx'
4
- s.version = '0.5.2'
7
+ s.version = FlyingSphinx::Version
5
8
  s.authors = ['Pat Allan']
6
9
  s.email = 'pat@freelancing-gods.com'
7
10
  s.summary = 'Sphinx in the Cloud'
@@ -12,6 +12,7 @@ require 'flying_sphinx/flag_as_deleted_job'
12
12
  require 'flying_sphinx/heroku_shared_adapter'
13
13
  require 'flying_sphinx/index_request'
14
14
  require 'flying_sphinx/tunnel'
15
+ require 'flying_sphinx/version'
15
16
 
16
17
  if defined?(Rails) && defined?(Rails::Railtie)
17
18
  require 'flying_sphinx/railtie'
@@ -1,5 +1,9 @@
1
1
  class FlyingSphinx::Configuration
2
2
  attr_reader :identifier, :api_key, :host, :port, :database_port, :mem_limit
3
+
4
+ FileIndexSettings = [:stopwords, :wordforms, :exceptions]
5
+ FileSourceSettings = [:mysql_ssl_cert, :mysql_ssl_key, :mysql_ssl_ca]
6
+ FileSettings = FileIndexSettings + FileSourceSettings
3
7
 
4
8
  def initialize(identifier = nil, api_key = nil)
5
9
  @identifier = identifier || identifier_from_env
@@ -16,16 +20,17 @@ class FlyingSphinx::Configuration
16
20
  def sphinx_configuration
17
21
  thinking_sphinx.generate
18
22
  set_database_settings
19
- set_wordforms
23
+ set_file_settings
20
24
 
21
25
  riddle.render
22
26
  end
23
27
 
24
- def wordform_file_pairs
25
- @wordform_file_pairs ||= begin
28
+ def file_setting_pairs(setting)
29
+ @file_setting_pairs ||= {}
30
+ @file_setting_pairs[setting] ||= begin
26
31
  pairs = {}
27
- wordform_sources.each_with_index do |source, index|
28
- pairs[source] = "#{base_path}/wordforms/#{index}.txt"
32
+ file_setting_sources(setting).each_with_index do |source, index|
33
+ pairs[source] = "#{base_path}/#{setting}/#{index}.txt"
29
34
  end
30
35
  pairs
31
36
  end
@@ -124,19 +129,45 @@ class FlyingSphinx::Configuration
124
129
  end
125
130
  end
126
131
 
127
- def set_wordforms
132
+ def set_file_settings
128
133
  riddle.indexes.each do |index|
129
- next unless index.respond_to?(:wordforms)
130
- index.wordforms = wordform_file_pairs[index.wordforms]
134
+ set_file_settings_for index, FileIndexSettings
135
+
136
+ next unless index.respond_to?(:sources)
137
+
138
+ index.sources.each do |source|
139
+ set_file_settings_for source, FileSourceSettings
140
+ end
141
+ end
142
+ end
143
+
144
+ def set_file_settings_for(object, settings)
145
+ settings.each do |setting|
146
+ next unless object.respond_to?(setting)
147
+ object.send "#{setting}=",
148
+ file_setting_pairs(setting)[object.send(setting)]
131
149
  end
132
150
  end
133
151
 
134
- def wordform_sources
135
- @wordform_sources ||= riddle.indexes.collect { |index|
136
- index.respond_to?(:wordforms) ? index.wordforms : nil
152
+ def file_setting_sources(setting)
153
+ @file_setting_sources ||= {}
154
+ @file_setting_sources[setting] ||= riddle.indexes.collect { |index|
155
+ file_settings_for_index(index, setting)
137
156
  }.flatten.compact.uniq
138
157
  end
139
-
158
+
159
+ def file_settings_for_index(index, setting)
160
+ settings = Array(file_setting_for(index, setting))
161
+ settings += index.sources.collect { |source|
162
+ file_setting_for(source, setting)
163
+ } if index.respond_to?(:sources)
164
+ settings
165
+ end
166
+
167
+ def file_setting_for(object, setting)
168
+ object.respond_to?(setting) ? object.send(setting) : nil
169
+ end
170
+
140
171
  def identifier_from_env
141
172
  ENV['FLYING_SPHINX_IDENTIFIER']
142
173
  end
@@ -71,11 +71,13 @@ class FlyingSphinx::IndexRequest
71
71
  end
72
72
 
73
73
  def update_sphinx_reference_files
74
- configuration.wordform_file_pairs.each do |local, remote|
75
- api.post '/add_file',
76
- :setting => 'wordforms',
77
- :file_name => remote.split('/').last,
78
- :content => open(local).read
74
+ FlyingSphinx::Configuration::FileSettings.each do |setting|
75
+ configuration.file_setting_pairs(setting).each do |local, remote|
76
+ api.post '/add_file',
77
+ :setting => setting.to_s,
78
+ :file_name => remote.split('/').last,
79
+ :content => open(local).read
80
+ end
79
81
  end
80
82
  end
81
83
 
@@ -0,0 +1,3 @@
1
+ module FlyingSphinx
2
+ Version = '0.6.0'
3
+ end
@@ -2,22 +2,23 @@ require 'spec_helper'
2
2
  require 'multi_json'
3
3
 
4
4
  describe FlyingSphinx::Configuration do
5
+ let(:api_server) { 'https://flying-sphinx.com/api/my' }
6
+
7
+ before :each do
8
+ FakeWeb.register_uri(:get, "#{api_server}/app",
9
+ :body => MultiJson.encode(
10
+ :server => 'foo.bar.com',
11
+ :port => 9319,
12
+ :database_port => 10001
13
+ )
14
+ )
15
+ end
16
+
5
17
  describe '#initialize' do
6
- let(:api_server) { 'https://flying-sphinx.com/api/my' }
7
18
  let(:api_key) { 'foo-bar-baz' }
8
19
  let(:identifier) { 'app@heroku.com' }
9
20
  let(:config) { FlyingSphinx::Configuration.new identifier, api_key }
10
21
 
11
- before :each do
12
- FakeWeb.register_uri(:get, "#{api_server}/app",
13
- :body => MultiJson.encode(
14
- :server => 'foo.bar.com',
15
- :port => 9319,
16
- :database_port => 10001
17
- )
18
- )
19
- end
20
-
21
22
  it "requests details from the server with the given API key" do
22
23
  config
23
24
  FakeWeb.should have_requested :get, "#{api_server}/app"
@@ -35,4 +36,149 @@ describe FlyingSphinx::Configuration do
35
36
  config.database_port.should == 10001
36
37
  end
37
38
  end
39
+
40
+ describe '#file_setting_pairs' do
41
+ let(:config) { FlyingSphinx::Configuration.new 'ident' }
42
+ let(:riddle) { ThinkingSphinx::Configuration.instance.configuration }
43
+ let(:base_path) { '/mnt/sphinx/flying-sphinx/ident' }
44
+
45
+ context 'index setting' do
46
+ it "pairs each local file path to a server file path" do
47
+ riddle.stub! :indexes => [
48
+ double('index', :wordforms => '/path/to/wordforms-foo.txt',
49
+ :sources => [double('source'), double('source')]),
50
+ double('index', :wordforms => '/path/to/wordforms-bar.txt',
51
+ :sources => [double('source'), double('source')])
52
+ ]
53
+
54
+ config.file_setting_pairs(:wordforms).should == {
55
+ '/path/to/wordforms-foo.txt' => "#{base_path}/wordforms/0.txt",
56
+ '/path/to/wordforms-bar.txt' => "#{base_path}/wordforms/1.txt"
57
+ }
58
+ end
59
+
60
+ it "doesn't duplicate multiple references to the same local file" do
61
+ riddle.stub! :indexes => [
62
+ double('index', :wordforms => '/path/to/wordforms-foo.txt',
63
+ :sources => [double('source'), double('source')]),
64
+ double('index', :wordforms => '/path/to/wordforms-foo.txt',
65
+ :sources => [double('source'), double('source')])
66
+ ]
67
+
68
+ config.file_setting_pairs(:wordforms).should == {
69
+ '/path/to/wordforms-foo.txt' => "#{base_path}/wordforms/0.txt"
70
+ }
71
+ end
72
+ end
73
+
74
+ context 'source setting' do
75
+ it "pairs each local file path to a server file path" do
76
+ riddle.stub! :indexes => [
77
+ double('index', :sources => [
78
+ double('source', :mysql_ssl_cert => '/path/to/cert-foo.txt'),
79
+ double('source', :mysql_ssl_cert => '/path/to/cert-bar.txt')
80
+ ]),
81
+ double('index', :sources => [
82
+ double('source', :mysql_ssl_cert => '/path/to/cert-baz.txt'),
83
+ double('source', :mysql_ssl_cert => nil)
84
+ ])
85
+ ]
86
+
87
+ config.file_setting_pairs(:mysql_ssl_cert).should == {
88
+ '/path/to/cert-foo.txt' => "#{base_path}/mysql_ssl_cert/0.txt",
89
+ '/path/to/cert-bar.txt' => "#{base_path}/mysql_ssl_cert/1.txt",
90
+ '/path/to/cert-baz.txt' => "#{base_path}/mysql_ssl_cert/2.txt"
91
+ }
92
+ end
93
+
94
+ it "doesn't duplicate multiple references to the same local file" do
95
+ riddle.stub! :indexes => [
96
+ double('index', :sources => [
97
+ double('source', :mysql_ssl_cert => '/path/to/cert-foo.txt'),
98
+ double('source', :mysql_ssl_cert => '/path/to/cert-bar.txt')
99
+ ]),
100
+ double('index', :sources => [
101
+ double('source', :mysql_ssl_cert => '/path/to/cert-foo.txt'),
102
+ double('source', :mysql_ssl_cert => nil)
103
+ ])
104
+ ]
105
+
106
+ config.file_setting_pairs(:mysql_ssl_cert).should == {
107
+ '/path/to/cert-foo.txt' => "#{base_path}/mysql_ssl_cert/0.txt",
108
+ '/path/to/cert-bar.txt' => "#{base_path}/mysql_ssl_cert/1.txt"
109
+ }
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '#sphinx_configuration' do
115
+ let(:config) { FlyingSphinx::Configuration.new 'ident' }
116
+ let(:riddle) { double('riddle configuration').as_null_object }
117
+ let(:base_path) { '/mnt/sphinx/flying-sphinx/ident' }
118
+ let(:source) { double('source') }
119
+
120
+ before :each do
121
+ ThinkingSphinx::Configuration.instance.stub!(
122
+ :generate => nil,
123
+ :configuration => riddle
124
+ )
125
+ FlyingSphinx::Tunnel.stub! :required? => false
126
+ end
127
+
128
+ it "sets database settings to match Flying Sphinx port forward" do
129
+ FlyingSphinx::Tunnel.stub! :required? => true
130
+
131
+ riddle.stub! :indexes => [
132
+ double('distributed index'),
133
+ double('index', :sources => [source])
134
+ ]
135
+
136
+ source.should_receive(:sql_host=).with('127.0.0.1')
137
+ source.should_receive(:sql_port=).with(10001)
138
+
139
+ config.sphinx_configuration
140
+ end
141
+
142
+ it "sets file path to match server directories for index settings" do
143
+ riddle.stub! :indexes => [
144
+ double('index', :wordforms => '/path/to/wordforms-foo.txt',
145
+ :sources => [double('source'), double('source')]),
146
+ double('index', :wordforms => '/path/to/wordforms-bar.txt',
147
+ :sources => [double('source'), double('source')]),
148
+ double('distributed index')
149
+ ]
150
+
151
+ riddle.indexes[0].should_receive(:wordforms=).
152
+ with("#{base_path}/wordforms/0.txt")
153
+ riddle.indexes[1].should_receive(:wordforms=).
154
+ with("#{base_path}/wordforms/1.txt")
155
+
156
+ config.sphinx_configuration
157
+ end
158
+
159
+ it "sets file path to match server directories for source settings" do
160
+ riddle.stub! :indexes => [
161
+ double('index', :sources => [
162
+ double('source', :mysql_ssl_cert => '/path/to/cert-foo.txt'),
163
+ double('source', :mysql_ssl_cert => '/path/to/cert-bar.txt')
164
+ ]),
165
+ double('index', :sources => [
166
+ double('source', :mysql_ssl_cert => '/path/to/cert-baz.txt'),
167
+ double('source', :mysql_ssl_cert => nil)
168
+ ]),
169
+ double('distributed index')
170
+ ]
171
+
172
+ riddle.indexes[0].sources[0].should_receive(:mysql_ssl_cert=).
173
+ with("#{base_path}/mysql_ssl_cert/0.txt")
174
+ riddle.indexes[0].sources[1].should_receive(:mysql_ssl_cert=).
175
+ with("#{base_path}/mysql_ssl_cert/1.txt")
176
+ riddle.indexes[1].sources[0].should_receive(:mysql_ssl_cert=).
177
+ with("#{base_path}/mysql_ssl_cert/2.txt")
178
+ riddle.indexes[1].sources[1].should_receive(:mysql_ssl_cert=).
179
+ with(nil)
180
+
181
+ config.sphinx_configuration
182
+ end
183
+ end
38
184
  end
@@ -4,7 +4,7 @@ describe FlyingSphinx::IndexRequest do
4
4
  let(:api) { FlyingSphinx::API.new 'foo', 'bar' }
5
5
  let(:configuration) {
6
6
  stub(:configuration, :api => api, :sphinx_configuration => 'foo {}',
7
- :wordform_file_pairs => {})
7
+ :file_setting_pairs => {})
8
8
  }
9
9
 
10
10
  let(:index_response) {
@@ -68,28 +68,36 @@ describe FlyingSphinx::IndexRequest do
68
68
  end
69
69
  end
70
70
 
71
- context 'with wordforms' do
72
- let(:file_params) {
73
- {:setting => 'wordforms', :file_name => 'bar.txt', :content => 'baz'}
74
- }
75
-
76
- before :each do
77
- configuration.stub!(:wordform_file_pairs => {'foo.txt' => 'bar.txt'})
78
- index_request.stub!(:open => double('file', :read => 'baz'))
79
- end
80
-
81
- it "sends the wordform file" do
82
- api.should_receive(:put).with('/', conf_params).and_return('ok')
83
- api.should_receive(:post).with('/add_file', file_params).
84
- and_return('ok')
85
- api.should_receive(:post).
86
- with('indices', index_params).and_return(index_response)
71
+ [
72
+ :stopwords, :wordforms, :exceptions, :mysql_ssl_cert, :mysql_ssl_key,
73
+ :mysql_ssl_ca
74
+ ].each do |setting|
75
+ context "with #{setting}" do
76
+ let(:file_params) {
77
+ {:setting => setting.to_s, :file_name => 'bar.txt', :content => 'baz'}
78
+ }
79
+
80
+ before :each do
81
+ configuration.stub!(:file_setting_pairs => {})
82
+ index_request.stub!(:open => double('file', :read => 'baz'))
83
+ end
87
84
 
88
- begin
89
- Timeout::timeout(0.2) {
90
- index_request.update_and_index
91
- }
92
- rescue Timeout::Error
85
+ it "sends the #{setting} file" do
86
+ api.should_receive(:put).with('/', conf_params).and_return('ok')
87
+ api.should_receive(:post).with('/add_file', file_params).
88
+ and_return('ok')
89
+ api.should_receive(:post).
90
+ with('indices', index_params).and_return(index_response)
91
+
92
+ configuration.should_receive(:file_setting_pairs).
93
+ with(setting).and_return({'foo.txt' => 'bar.txt'})
94
+
95
+ begin
96
+ Timeout::timeout(0.2) {
97
+ index_request.update_and_index
98
+ }
99
+ rescue Timeout::Error
100
+ end
93
101
  end
94
102
  end
95
103
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: flying-sphinx
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.5.2
5
+ version: 0.6.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Pat Allan
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-07-28 00:00:00 +10:00
13
+ date: 2011-07-31 00:00:00 +10:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -187,6 +187,7 @@ files:
187
187
  - lib/flying_sphinx/sinatra.rb
188
188
  - lib/flying_sphinx/tasks.rb
189
189
  - lib/flying_sphinx/tunnel.rb
190
+ - lib/flying_sphinx/version.rb
190
191
  - spec/spec_helper.rb
191
192
  - spec/specs/configuration_spec.rb
192
193
  - spec/specs/delayed_delta_spec.rb