picky-client 4.0.6 → 4.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,87 @@
1
+ module Picky
2
+ class Client
3
+
4
+ # An ActiveRecord integration that uses the
5
+ # Picky HTTP client to send index updates
6
+ # back to a Picky server (usually Sinatra).
7
+ #
8
+ # Examples:
9
+ # # Note that the Person will
10
+ # # be indexed in three indexes.
11
+ # #
12
+ # class Person < ActiveRecord::Base
13
+ # extend Picky::ActiveRecord.new # All attributes will be sent to index "people".
14
+ # extend Picky::ActiveRecord.new('name') # Only the name will be sent to index "people".
15
+ # extend Picky::ActiveRecord.new('surname', index: 'special_index') # Only the surname will be sent to index "special_index".
16
+ # # Use the given Client to send index data.
17
+ # #
18
+ # extend Picky::ActiveRecord.new(client: Picky::Client.new(host: 'localhost', port: '4567', path: '/indexing'))
19
+ # extend Picky::ActiveRecord.new(host: 'localhost', port: '4567', path: '/indexing')
20
+ # end
21
+ #
22
+ # florian = Person.new name: "Florian", surname: "Hanke"
23
+ # florian.save
24
+ # florian.update_attributes name: "Peter"
25
+ #
26
+ class ActiveRecord < Module
27
+
28
+ # Takes an array of indexed attributes/methods
29
+ # and options.
30
+ #
31
+ # Note: See class documentation for a description.
32
+ #
33
+ # Examples:
34
+ # Picky::Client::ActiveRecord.new
35
+ # Picky::Client::ActiveRecord.new('name', 'surname', index: 'some_index_name')
36
+ #
37
+ # Options:
38
+ # * index: The index name to save to.
39
+ # * host: The host where the Picky server is.
40
+ # * port: The host which the Picky server listens to.
41
+ # * path: The path the Picky server uses for index updates (use e.f. extend Picky::Sinatra::IndexActions to open up a HTTP indexing interface).
42
+ # * client: The client to use if you want to pass in your own (host, port, path options will be ignored).
43
+ #
44
+ def initialize *attributes
45
+ options = {}
46
+ options = attributes.pop if attributes.last.respond_to?(:to_hash)
47
+
48
+ # Default path for indexing is '/'.
49
+ #
50
+ client = options[:client] ||
51
+ (options[:path] ||= '/') && Picky::Client.new(options)
52
+
53
+ self.class.class_eval do
54
+ index_name = options[:index]
55
+
56
+ define_method :extended do |model|
57
+ attributes = nil if attributes.empty?
58
+ index_name ||= model.table_name
59
+
60
+ # Only after the database has actually
61
+ # updated the data do we want to index.
62
+ #
63
+ model.after_commit do |object|
64
+ data = { 'id' => object.id }
65
+
66
+ if object.destroyed?
67
+ client.remove index_name, data
68
+ else
69
+ (attributes || object.attributes.keys).each do |attr|
70
+ data[attr] = object.respond_to?(attr) &&
71
+ object.send(attr) ||
72
+ object[attr]
73
+ end
74
+
75
+ client.replace index_name, data
76
+ end
77
+ end
78
+
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,32 @@
1
+ module Picky
2
+ class Client
3
+
4
+ # TODO Rename?
5
+ #
6
+ # Parameters:
7
+ # * index_name: An index that exists in the Picky server.
8
+ # * data: A hash in the form of { :id => 1234, :attr1 => 'attr1', :attr2 => 'attr2', ... }.
9
+ #
10
+ def replace index_name, data
11
+ request Net::HTTP::Post.new(self.path), index_name, data
12
+ end
13
+
14
+ # TODO Rename?
15
+ #
16
+ # Parameters:
17
+ # * index_name: An index that exists in the Picky server.
18
+ # * data: A hash in the form of { :id => 1234 }.
19
+ #
20
+ def remove index_name, data
21
+ request Net::HTTP::Delete.new(self.path), index_name, data
22
+ end
23
+
24
+ # Sends a request to the Picky server.
25
+ #
26
+ def request request, index_name, data
27
+ request.form_data = { :index => index_name, :data => data }
28
+ Net::HTTP.new(self.host, self.port).start { |http| http.request request }
29
+ end
30
+
31
+ end
32
+ end
data/lib/picky-client.rb CHANGED
@@ -5,6 +5,9 @@ require 'yajl'
5
5
 
6
6
  dir = File.dirname __FILE__
7
7
  require File.expand_path('picky-client/client', dir)
8
+ require File.expand_path('picky-client/client_index', dir)
8
9
  require File.expand_path('picky-client/convenience', dir)
9
10
  require File.expand_path('picky-client/helper', dir)
10
- require File.expand_path('picky-client/extensions/object', dir)
11
+ require File.expand_path('picky-client/extensions/object', dir)
12
+
13
+ require File.expand_path('picky-client/client/active_record', dir)
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+
3
+ describe Picky::Client::ActiveRecord do
4
+
5
+ let(:fake_ar) do
6
+ Class.new do
7
+
8
+ attr_reader :id, :name, :surname
9
+
10
+ def initialize id, name, surname
11
+ @id, @name, @surname = id, name, surname
12
+ end
13
+
14
+ class << self
15
+
16
+ attr_accessor :after_commits
17
+
18
+ def after_commit &block
19
+ self.after_commits ||= []
20
+ self.after_commits << block
21
+ end
22
+
23
+ def table_name
24
+ 'some_index_name'
25
+ end
26
+
27
+ end
28
+
29
+ def attributes
30
+ { 'id' => nil, 'name' => nil, 'surname' => nil }
31
+ end
32
+
33
+ def save
34
+ after_commit
35
+ end
36
+
37
+ def destroy
38
+ @destroyed = true
39
+ after_commit
40
+ end
41
+
42
+ def destroyed?
43
+ @destroyed
44
+ end
45
+
46
+ def after_commit
47
+ self.class.after_commits.each do |block|
48
+ block.call self
49
+ end
50
+ end
51
+
52
+ end
53
+ end
54
+
55
+ it 'is a module' do
56
+ described_class.should be_kind_of(Module)
57
+ end
58
+
59
+ context 'default module' do
60
+ let(:ar_module) { described_class.new }
61
+
62
+ it 'is (also) a module' do
63
+ ar_module.should be_kind_of(Module)
64
+ end
65
+ end
66
+
67
+ # describe 'directly extend' do
68
+ # let(:ar) { fake_ar.extend(described_class) }
69
+ #
70
+ # it 'calls the right method in the client' do
71
+ # ar.save
72
+ # end
73
+ #
74
+ # it 'calls the right method in the client' do
75
+ # ar.destroy
76
+ # end
77
+ #
78
+ # end
79
+
80
+ context 'with params' do
81
+ let(:client) { stub :client }
82
+ context 'with client' do
83
+ let(:ar_module) { described_class.new :client => client }
84
+ let(:ar) { fake_ar.extend(ar_module).new(1, 'Niko', 'Dittmann') }
85
+
86
+ it 'is a module' do
87
+ ar_module.should be_kind_of(Module)
88
+ end
89
+
90
+ it 'calls the right method in the client' do
91
+ client.should_receive(:replace).once.with 'some_index_name', { 'id' => 1, 'name' => 'Niko', 'surname' => 'Dittmann' }
92
+
93
+ ar.save
94
+ end
95
+
96
+ it 'calls the right method in the client' do
97
+ client.should_receive(:remove).once.with 'some_index_name', { 'id' => 1 }
98
+
99
+ ar.destroy
100
+ end
101
+
102
+ end
103
+
104
+ context 'with client and index' do
105
+ let(:ar_module) { described_class.new :client => client, :index => 'some_other_index_name' }
106
+ let(:ar) { fake_ar.extend(ar_module).new(1, 'Niko', 'Dittmann') }
107
+
108
+ it 'is a module' do
109
+ ar_module.should be_kind_of(Module)
110
+ end
111
+
112
+ it 'calls the right method in the client' do
113
+ client.should_receive(:replace).once.with 'some_other_index_name', { 'id' => 1, 'name' => 'Niko', 'surname' => 'Dittmann' }
114
+
115
+ ar.save
116
+ end
117
+
118
+ it 'calls the right method in the client' do
119
+ client.should_receive(:remove).once.with 'some_other_index_name', { 'id' => 1 }
120
+
121
+ ar.destroy
122
+ end
123
+ end
124
+ context 'with client and specific attributes' do
125
+ let(:ar_module) { described_class.new 'name', :client => client }
126
+ let(:ar) { fake_ar.extend(ar_module).new(1, 'Niko', 'Dittmann') }
127
+
128
+ it 'is a module' do
129
+ ar_module.should be_kind_of(Module)
130
+ end
131
+
132
+ it 'calls the right method in the client' do
133
+ client.should_receive(:replace).once.with 'some_index_name', { 'id' => 1, 'name' => 'Niko' }
134
+
135
+ ar.save
136
+ end
137
+
138
+ it 'calls the right method in the client' do
139
+ client.should_receive(:remove).once.with 'some_index_name', { 'id' => 1 }
140
+
141
+ ar.destroy
142
+ end
143
+ end
144
+ context 'standard client' do
145
+ it 'instantiates the client correctly' do
146
+ Picky::Client.should_receive(:new).once.with :path => '/'
147
+
148
+ described_class.new
149
+ end
150
+ it 'instantiates the client correctly' do
151
+ Picky::Client.should_receive(:new).once.with :host => 'some_host', :port => :some_port, :path => '/bla'
152
+
153
+ described_class.new :host => 'some_host', :port => :some_port, :path => '/bla'
154
+ end
155
+ end
156
+ end
157
+
158
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Picky::Client do
4
+
5
+ let(:client) { described_class.new path: '/' }
6
+
7
+ describe 'replace' do
8
+ it 'delegates to the request method' do
9
+ client.should_receive(:request).once.with anything, :some_index_name, :some_data
10
+
11
+ client.replace :some_index_name, :some_data
12
+ end
13
+ end
14
+
15
+ describe 'remove' do
16
+ it 'delegates to the request method' do
17
+ client.should_receive(:request).once.with anything, :some_index_name, :some_data
18
+
19
+ client.remove :some_index_name, :some_data
20
+ end
21
+ end
22
+
23
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picky-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.6
4
+ version: 4.0.7
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-01-02 00:00:00.000000000 Z
12
+ date: 2012-01-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yajl-ruby
16
- requirement: &70178924113460 !ruby/object:Gem::Requirement
16
+ requirement: &70126973731340 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.7.8
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70178924113460
24
+ version_requirements: *70126973731340
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &70178924112400 !ruby/object:Gem::Requirement
27
+ requirement: &70126973729580 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: 3.0.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70178924112400
35
+ version_requirements: *70126973729580
36
36
  description: Picky Client
37
37
  email: florian.hanke+picky-client@gmail.com
38
38
  executables: []
@@ -42,7 +42,9 @@ extra_rdoc_files:
42
42
  files:
43
43
  - lib/picky-client/aux/cursed.rb
44
44
  - lib/picky-client/aux/terminal.rb
45
+ - lib/picky-client/client/active_record.rb
45
46
  - lib/picky-client/client.rb
47
+ - lib/picky-client/client_index.rb
46
48
  - lib/picky-client/convenience.rb
47
49
  - lib/picky-client/extensions/object.rb
48
50
  - lib/picky-client/helper.rb
@@ -59,6 +61,8 @@ files:
59
61
  - javascripts/picky.min.js
60
62
  - README.rdoc
61
63
  - spec/picky-client/aux/terminal_spec.rb
64
+ - spec/picky-client/client/active_record_spec.rb
65
+ - spec/picky-client/client_index_spec.rb
62
66
  - spec/picky-client/client_spec.rb
63
67
  - spec/picky-client/convenience_spec.rb
64
68
  - spec/picky-client/extensions/object_spec.rb
@@ -90,6 +94,8 @@ specification_version: 3
90
94
  summary: Picky Ruby Search Engine Client
91
95
  test_files:
92
96
  - spec/picky-client/aux/terminal_spec.rb
97
+ - spec/picky-client/client/active_record_spec.rb
98
+ - spec/picky-client/client_index_spec.rb
93
99
  - spec/picky-client/client_spec.rb
94
100
  - spec/picky-client/convenience_spec.rb
95
101
  - spec/picky-client/extensions/object_spec.rb