oedipus 0.0.13 → 0.0.14

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.
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # Oedipus: Sphinx 2 Search Client for Ruby
2
2
 
3
3
  Oedipus is a client for the Sphinx search engine (>= 2.0.2), with support for
4
- real-time indexes and multi and/or multi-dimensional faceted searches.
4
+ real-time indexes and multi-dimensional faceted searches.
5
5
 
6
6
  It is not a clone of the PHP API, rather it is written from the ground up,
7
7
  wrapping the SphinxQL API offered by searchd. Nor is it a plugin for
8
- ActiveRecord or DataMapper... though this will follow in separate gems (see
8
+ ActiveRecord or DataMapper... though this will be offered in separate gems (see
9
9
  [oedipus-dm](https://github.com/d11wtq/oedipus-dm)).
10
10
 
11
11
  Oedipus provides a level of abstraction in terms of the ease with which faceted
@@ -21,14 +21,17 @@ Oedipus does not (yet) provide wrappers for indexing that data via ruby [1].
21
21
 
22
22
  ## Dependencies
23
23
 
24
- * ruby (>= 1.9)
25
- * sphinx (>= 2.0.2)
26
- * mysql client development libraries (>= 4.1)
24
+ * ruby >= 1.9
25
+ * sphinx >= 2.0.2
26
+ * mysql dev libs >= 4.1
27
27
 
28
- The gem builds a small (tiny) native extension for interfacing with mysql, as
29
- existing gems either did not support multi-queries, or were too flaky
30
- (i.e. ruby-mysql). I will add a pure-ruby option in due course (it requires
31
- implementing a relatively small subset of the mysql 4.1 protocol).
28
+ ## Installation
29
+
30
+ Via rubygems:
31
+
32
+ ```
33
+ gem install oedipus
34
+ ```
32
35
 
33
36
  ## Usage
34
37
 
@@ -39,7 +42,30 @@ The following features are all currently implemented.
39
42
  ``` ruby
40
43
  require "oedipus"
41
44
 
42
- sphinx = Oedipus.connect('localhost:9306') # sphinxql host
45
+ sphinx = Oedipus.connect('127.0.0.1:9306') # sphinxql host
46
+ ```
47
+
48
+ **NOTE:** Don't connect to the named host 'localhost', since the MySQL library
49
+ will try to use a UNIX socket instead of a TCP connection, which Sphinx doesn't
50
+ currently support.
51
+
52
+ Connections can be re-used by calling `Oedipus.connection` once connected.
53
+
54
+ ``` ruby
55
+ sphinx = Oedipus.connection
56
+ ```
57
+
58
+ If you're using Oedipus in a Rails application, you may wish to call `connect`
59
+ inside an initializer and then obtain that connection in your application, by
60
+ calling `connection`.
61
+
62
+ If you need to manage multiple connections, you may specify names for each
63
+ connection.
64
+
65
+ ``` ruby
66
+ Oedipus.connect("other-host.tld:9306", :other)
67
+
68
+ sphinx = Oedipus.connection(:other)
43
69
  ```
44
70
 
45
71
  ### Inserting (real-time indexes)
@@ -76,7 +102,6 @@ sphinx[:articles].update(7, views: 103)
76
102
 
77
103
  ``` ruby
78
104
  sphinx[:articles].delete(7)
79
- # => true
80
105
  ```
81
106
 
82
107
  ### Fetching a known document (by ID)
@@ -90,12 +115,6 @@ record = sphinx[:articles].fetch(7)
90
115
 
91
116
  You perform queries by invoking `#search` on the index.
92
117
 
93
- Oedipus makes no attempt to provide an abstraction layer for the fulltext
94
- query itself. I believe this would not be flexible enough. Sphinx fulltext
95
- queries are extremely featureful, very dense and concise; a ruby solution
96
- would only be lengthier and harder to understand, IMHO. Perhaps such an
97
- abstraction could be provided by a separate gem.
98
-
99
118
 
100
119
  ``` ruby
101
120
  results = sphinx[:articles].search("badgers", limit: 2)
@@ -231,8 +250,8 @@ attribute differently.
231
250
  Note that Sphinx applies a limit of 20 by default, so you probably want to specify
232
251
  a limit yourself. You are bound by your `max_matches` setting in sphinx.conf.
233
252
 
234
- Note that the meta data will still indicate the actual number of results that matched;
235
- you simply get a smaller collection of materialized records.
253
+ The meta data will still indicate the actual number of results that matched; you simply
254
+ get a smaller collection of materialized records.
236
255
 
237
256
  ``` ruby
238
257
  sphinx[:articles].search("bobcats", limit: 50)
@@ -245,8 +264,8 @@ A faceted search takes a base query and a set of additional queries that are
245
264
  variations on it. Oedipus makes this simple by allowing your facets to inherit
246
265
  from the base query.
247
266
 
248
- Oedipus allows you to replace '%{query}' in your facets with whatever was in the
249
- original query. This can be useful if you want to provide facets that only
267
+ Oedipus allows you to replace `'%{query}'` in your facets with whatever was in
268
+ the original query. This can be useful if you want to provide facets that only
250
269
  perform the search in the title of the document (`"@title (%{query})"`) for
251
270
  example.
252
271
 
@@ -380,11 +399,6 @@ To run the unit tests alone, without the need for Sphinx:
380
399
  If you have made changes to the C extension, those changes will be compiled and installed
381
400
  (to the lib/ directory) before the specs are run.
382
401
 
383
- You may also compile the C extension and run the specs separately, if you prefer:
384
-
385
- bundle exec rake compile
386
- bundle exec rspec spec/unit/
387
-
388
402
  ### Footnotes
389
403
 
390
404
  [1]: In practice I find such an abstraction not to be very useful, as it assumes a single-server setup
@@ -399,10 +413,9 @@ You may also compile the C extension and run the specs separately, if you prefer
399
413
 
400
414
  ## Future Plans
401
415
 
402
- * Integration ActiveRecord (DataMapper support has already been added)
416
+ * Integration ActiveRecord
403
417
  * Support for re-indexing non-realtime indexes from ruby code
404
418
  * Distributed index support (sharding writes between indexes)
405
- * Make C extension optional and provide an implementation in pure-ruby
406
419
  * Query translation layer for Lucene-style AND/OR/NOT and attribute:value interpretation
407
420
  * Fulltext query sanitization for unsafe user input (e.g. @@missing field)
408
421
 
@@ -0,0 +1,56 @@
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
+ class Connection
12
+ module Registry
13
+ # Connect to Sphinx running SphinxQL.
14
+ #
15
+ # Connections are cached for re-use.
16
+ #
17
+ # @example
18
+ # c = Oedipus.connect("127.0.0.1:9306")
19
+ # c = Oedipus.connect(host: "127.0.0.1", port: 9306)
20
+ # c = Oedipus.connect("127.0.0.1:9306", :dist_host)
21
+ #
22
+ # @param [String|Hash] server
23
+ # a 'hostname:port' string, or
24
+ # a Hash with :host and :port keys
25
+ #
26
+ # @param [Object] key
27
+ # an optional name for the connection
28
+ #
29
+ # @return [Connection]
30
+ # a client connected to SphinxQL
31
+ def connect(options, key = :default)
32
+ connections[key] = Connection.new(options)
33
+ end
34
+
35
+ # Lookup an already connected connection.
36
+ #
37
+ # @example
38
+ # c = Oedipus.connection
39
+ # c = Oedipus.connection(:dist_host)
40
+ #
41
+ # @param [Object] key
42
+ # an optional name for the connection
43
+ #
44
+ # @return [Connection]
45
+ # a client connected to SphinxQL
46
+ def connection(key = :default)
47
+ raise ArgumentError, "Connection #{key} is not defined" unless connections.key?(key)
48
+ connections[key]
49
+ end
50
+
51
+ def connections
52
+ @connections ||= {}
53
+ end
54
+ end
55
+ end
56
+ end
@@ -49,6 +49,8 @@ module Oedipus
49
49
  Index.new(index_name, self)
50
50
  end
51
51
 
52
+ alias_method :index, :[]
53
+
52
54
  # Execute one or more queries in a batch.
53
55
  #
54
56
  # Queries should be separated by semicolons.
@@ -8,5 +8,5 @@
8
8
  ##
9
9
 
10
10
  module Oedipus
11
- VERSION = "0.0.13"
11
+ VERSION = "0.0.14"
12
12
  end
data/lib/oedipus.rb CHANGED
@@ -30,30 +30,11 @@ require "oedipus/query_builder"
30
30
  require "oedipus/connection_error"
31
31
  require "oedipus/connection"
32
32
  require "oedipus/connection/pool"
33
+ require "oedipus/connection/registry"
33
34
 
34
35
  require "oedipus/index"
35
36
 
36
37
  module Oedipus
37
38
  extend Comparison::Shortcuts
38
-
39
- class << self
40
- # Connect to Sphinx running SphinxQL.
41
- #
42
- # @example
43
- # c = Oedipus.connect("localhost:9306")
44
- # c = Oedipus.connect(host: "localhost", port: 9306)
45
- #
46
- # @param [String] server
47
- # a 'hostname:port' string
48
- #
49
- # @param [Hash] options
50
- # a Hash with :host and :port keys
51
- #
52
- # @return [Connection]
53
- # a client connected to SphinxQL
54
- def connect(options)
55
- # TODO: Add pooling
56
- Connection.new(options)
57
- end
58
- end
39
+ extend Connection::Registry
59
40
  end
@@ -0,0 +1,59 @@
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 "spec_helper"
11
+ require "oedipus/rspec/test_harness"
12
+
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 }
25
+
26
+ let(:registry) do
27
+ Object.new.tap { |o| o.send(:extend, Oedipus::Connection::Registry) }
28
+ end
29
+
30
+ describe "#connect" do
31
+ it "makes a new connection to a SphinxQL host" do
32
+ registry.connect(searchd_host).should be_a_kind_of(Oedipus::Connection)
33
+ end
34
+ end
35
+
36
+ describe "#connection" do
37
+ context "without a name" do
38
+ let(:conn) { registry.connect(searchd_host) }
39
+
40
+ it "returns an existing connection" do
41
+ conn.should equal registry.connection
42
+ end
43
+ end
44
+
45
+ context "with a name" do
46
+ let(:conn) { registry.connect(searchd_host, :bob) }
47
+
48
+ it "returns the named connection" do
49
+ conn.should equal registry.connection(:bob)
50
+ end
51
+ end
52
+
53
+ context "with a bad name" do
54
+ it "raises an ArgumentError" do
55
+ expect { registry.connection(:wrong) }.to raise_error(ArgumentError)
56
+ end
57
+ end
58
+ end
59
+ end
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.13
4
+ version: 0.0.14
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-06 00:00:00.000000000 Z
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &23194300 !ruby/object:Gem::Requirement
16
+ requirement: &12537160 !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: *23194300
24
+ version_requirements: *12537160
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake-compiler
27
- requirement: &23193860 !ruby/object:Gem::Requirement
27
+ requirement: &12535680 !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: *23193860
35
+ version_requirements: *12535680
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
@@ -73,6 +73,7 @@ files:
73
73
  - lib/oedipus/comparison/shortcuts.rb
74
74
  - lib/oedipus/connection.rb
75
75
  - lib/oedipus/connection/pool.rb
76
+ - lib/oedipus/connection/registry.rb
76
77
  - lib/oedipus/connection_error.rb
77
78
  - lib/oedipus/index.rb
78
79
  - lib/oedipus/query_builder.rb
@@ -80,6 +81,7 @@ files:
80
81
  - lib/oedipus/version.rb
81
82
  - oedipus.gemspec
82
83
  - spec/data/.gitkeep
84
+ - spec/integration/connection/registry_spec.rb
83
85
  - spec/integration/connection_spec.rb
84
86
  - spec/integration/index_spec.rb
85
87
  - spec/spec_helper.rb
@@ -111,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
113
  version: '0'
112
114
  segments:
113
115
  - 0
114
- hash: 1539164909782359047
116
+ hash: -1945313164651030981
115
117
  required_rubygems_version: !ruby/object:Gem::Requirement
116
118
  none: false
117
119
  requirements:
@@ -120,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
122
  version: '0'
121
123
  segments:
122
124
  - 0
123
- hash: 1539164909782359047
125
+ hash: -1945313164651030981
124
126
  requirements: []
125
127
  rubyforge_project: oedipus
126
128
  rubygems_version: 1.8.11
@@ -129,6 +131,7 @@ specification_version: 3
129
131
  summary: Sphinx 2 Search Client for Ruby
130
132
  test_files:
131
133
  - spec/data/.gitkeep
134
+ - spec/integration/connection/registry_spec.rb
132
135
  - spec/integration/connection_spec.rb
133
136
  - spec/integration/index_spec.rb
134
137
  - spec/spec_helper.rb