ts-datetime-delta 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,16 +4,20 @@ h2. Installation
4
4
 
5
5
  You'll need Thinking Sphinx 1.3.0 or later.
6
6
 
7
- <pre><code>gem install ts-datetime-delta --source http://gemcutter.org</code></pre>
7
+ <pre><code>gem install ts-datetime-delta</code></pre>
8
8
 
9
- In your @environment.rb@ file, with the rest of your gem dependencies:
9
+ In your Gemfile, you can use it like so:
10
+
11
+ <pre><code>gem 'ts-datetime-delta', '~> 1.0.2',
12
+ :require => 'thinking_sphinx/deltas/datetime_delta'</code></pre>
13
+
14
+ Or if you're still on Rails 2, then put this in your @environment.rb@ file with the rest of your gem dependencies:
10
15
 
11
16
  <pre><code>config.gem 'ts-datetime-delta',
12
17
  :lib => 'thinking_sphinx/deltas/datetime_delta'
13
- :version => '>= 1.0.0',
14
- :source => 'http://gemcutter.org'</code></pre>
18
+ :version => '>= 1.0.0'</code></pre>
15
19
 
16
- And add the following line to the bottom of your @Rakefile@:
20
+ No matter which version of Rails, you'll need to add the following line to the bottom of your @Rakefile@:
17
21
 
18
22
  <pre><code>require 'thinking_sphinx/deltas/datetime_delta/tasks'</code></pre>
19
23
 
@@ -23,7 +27,7 @@ For the indexes you want to use this delta approach, make sure you set that up i
23
27
 
24
28
  <pre><code>define_index do
25
29
  # ...
26
-
30
+
27
31
  set_property :delta => :datetime
28
32
  end</code></pre>
29
33
 
@@ -45,6 +49,11 @@ The shorthand version is:
45
49
 
46
50
  <pre><code>rake ts:in:delta</code></pre>
47
51
 
52
+ h2. Contributors
53
+
54
+ * "W. Andrew Loe III":http://andrewloe.com/ - Environment variable for disabling merging.
55
+ * "Kirill Maximov":http://kirblog.idetalk.com - Handling nil timestamp column values for toggled checks.
56
+
48
57
  h2. Copyright
49
58
 
50
- Copyright (c) 2009 Pat Allan, and released under an MIT Licence.
59
+ Copyright (c) 2009-2012 Pat Allan, and released under an MIT Licence.
@@ -1,121 +1,139 @@
1
1
  # Datetime Deltas for Thinking Sphinx
2
- #
2
+ #
3
3
  # This documentation is aimed at those reading the code. If you're looking for
4
4
  # a guide to Thinking Sphinx and/or deltas, I recommend you start with the
5
5
  # Thinking Sphinx site instead - or the README for this library at the very
6
6
  # least.
7
- #
7
+ #
8
8
  # @author Patrick Allan
9
9
  # @see http://ts.freelancing-gods.com Thinking Sphinx
10
- #
10
+ #
11
11
  class ThinkingSphinx::Deltas::DatetimeDelta < ThinkingSphinx::Deltas::DefaultDelta
12
12
  attr_accessor :column, :threshold
13
-
13
+
14
+ def self.index
15
+ ThinkingSphinx.context.indexed_models.collect { |model|
16
+ model.constantize
17
+ }.select { |model|
18
+ model.define_indexes
19
+ model.delta_indexed_by_sphinx?
20
+ }.each do |model|
21
+ model.sphinx_indexes.select { |index|
22
+ index.delta? && index.delta_object.respond_to?(:delayed_index)
23
+ }.each { |index|
24
+ index.delta_object.delayed_index(index.model)
25
+ }
26
+ end
27
+ end
28
+
14
29
  # Initialises the Delta object for the given index and settings. All handled
15
30
  # by Thinking Sphinx, so you shouldn't need to call this method yourself in
16
31
  # general day-to-day situations.
17
- #
32
+ #
18
33
  # @example
19
34
  # ThinkingSphinx::Deltas::DatetimeDelta.new index,
20
35
  # :delta_column => :updated_at,
21
36
  # :threshold => 1.day
22
- #
37
+ #
23
38
  # @param [ThinkingSphinx::Index] index the index using this delta object
24
39
  # @param [Hash] options a hash of options for the index
25
40
  # @option options [Symbol] :delta_column (:updated_at) The column to use for
26
41
  # tracking when a record has changed. Default to :updated_at.
27
42
  # @option options [Integer] :threshold (1.day) The window of time to store
28
43
  # changes for, in seconds. Defaults to one day.
29
- #
44
+ #
30
45
  def initialize(index, options = {})
31
46
  @index = index
32
47
  @column = options.delete(:delta_column) || :updated_at
33
48
  @threshold = options.delete(:threshold) || 1.day
34
49
  end
35
-
50
+
36
51
  # Does absolutely nothing, beyond returning true. Thinking Sphinx expects
37
52
  # this method, though, and we don't want to use the inherited behaviour from
38
53
  # DefaultDelta.
39
- #
54
+ #
40
55
  # All the real indexing logic is done by the delayed_index method.
41
- #
56
+ #
42
57
  # @param [Class] model the ActiveRecord model to index.
43
58
  # @param [ActiveRecord::Base] instance the instance of the given model that
44
59
  # has changed. Optional.
45
60
  # @return [Boolean] true
46
61
  # @see #delayed_index
47
- #
62
+ #
48
63
  def index(model, instance = nil)
49
64
  # do nothing
50
65
  true
51
66
  end
52
-
67
+
53
68
  # Processes the delta index for the given model, and then merges the relevant
54
69
  # core and delta indexes together. By default, the output of these indexer
55
70
  # commands are printed to stdout. If you'd rather it didn't, set
56
71
  # ThinkingSphinx.suppress_delta_output to true.
57
- #
72
+ #
58
73
  # @param [Class] model the ActiveRecord model to index
59
74
  # @return [Boolean] true
60
- #
75
+ #
61
76
  def delayed_index(model)
62
77
  config = ThinkingSphinx::Configuration.instance
63
78
  rotate = ThinkingSphinx.sphinx_running? ? " --rotate" : ""
64
-
79
+
65
80
  output = `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file}#{rotate} #{model.delta_index_names.join(' ')}`
66
-
81
+
82
+
67
83
  model.sphinx_indexes.select(&:delta?).each do |index|
68
84
  output += `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file}#{rotate} --merge #{index.core_name} #{index.delta_name} --merge-dst-range sphinx_deleted 0 0`
69
- end
85
+ end unless ENV['DISABLE_MERGE'] == 'true'
86
+
70
87
  puts output unless ThinkingSphinx.suppress_delta_output?
71
-
88
+
72
89
  true
73
90
  end
74
-
91
+
75
92
  # Toggles the given instance to be flagged as part of the next delta indexing.
76
93
  # For datetime deltas, this means do nothing at all.
77
- #
94
+ #
78
95
  # @param [ActiveRecord::Base] instance the instance to be toggled
79
- #
96
+ #
80
97
  def toggle(instance)
81
98
  # do nothing
82
99
  end
83
-
100
+
84
101
  # Report whether a given instance is considered toggled (part of the next
85
102
  # delta process). For datetime deltas, this is true if the delta column
86
103
  # (updated_at by default) has a value within the threshold. Otherwise, false
87
104
  # is returned.
88
- #
105
+ #
89
106
  # @param [ActiveRecord::Base] instance the instance to check
90
107
  # @return [Boolean] True if within the threshold window, otherwise false.
91
- #
108
+ #
92
109
  def toggled(instance)
93
- instance.send(@column) > @threshold.ago
110
+ res = instance.send(@column)
111
+ res && (res > @threshold.ago)
94
112
  end
95
-
113
+
96
114
  # Returns the SQL query that resets the model data after a normal index. For
97
115
  # datetime deltas, nothing needs to be done, so this method returns nil.
98
- #
116
+ #
99
117
  # @param [Class] model The ActiveRecord model that is requesting the query
100
118
  # @return [NilClass] Always nil
101
- #
119
+ #
102
120
  def reset_query(model)
103
121
  nil
104
122
  end
105
-
123
+
106
124
  # A SQL condition (as part of the WHERE clause) that limits the result set to
107
125
  # just the delta data, or all data, depending on whether the toggled argument
108
- # is true or not. For datetime deltas, the former value is a check on the
126
+ # is true or not. For datetime deltas, the former value is a check on the
109
127
  # delta column being within the threshold. In the latter's case, no condition
110
128
  # is needed, so nil is returned.
111
- #
129
+ #
112
130
  # @param [Class] model The ActiveRecord model to generate the SQL condition
113
131
  # for.
114
132
  # @param [Boolean] toggled Whether the query should request delta documents or
115
133
  # all documents.
116
134
  # @return [String, NilClass] The SQL condition if the toggled version is
117
135
  # requested, otherwise nil.
118
- #
136
+ #
119
137
  def clause(model, toggled)
120
138
  if toggled
121
139
  "#{model.quoted_table_name}.#{model.connection.quote_column_name(@column.to_s)}" +
@@ -1,26 +1,15 @@
1
1
  namespace :thinking_sphinx do
2
2
  namespace :index do
3
- desc "Index Thinking Sphinx datetime delta indexes"
3
+ desc "Index Thinking Sphinx datetime delta indices"
4
4
  task :delta => :app_env do
5
- ThinkingSphinx.context.indexed_models.collect { |model|
6
- model.constantize
7
- }.select { |model|
8
- model.define_indexes
9
- model.delta_indexed_by_sphinx?
10
- }.each do |model|
11
- model.sphinx_indexes.select { |index|
12
- index.delta? && index.delta_object.respond_to?(:delayed_index)
13
- }.each { |index|
14
- index.delta_object.delayed_index(index.model)
15
- }
16
- end
5
+ ThinkingSphinx::Deltas::DatetimeDelta.index
17
6
  end
18
7
  end
19
8
  end
20
9
 
21
10
  namespace :ts do
22
11
  namespace :in do
23
- desc "Index Thinking Sphinx datetime delta indexes"
12
+ desc "Index Thinking Sphinx datetime delta indices"
24
13
  task :delta => "thinking_sphinx:index:delta"
25
14
  end
26
15
  end
@@ -1,12 +1,13 @@
1
1
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
2
 
3
3
  require 'rubygems'
4
- require 'spec'
5
- require 'spec/autorun'
4
+ require 'rspec'
6
5
 
7
- require "thinking_sphinx"
6
+ require 'active_support'
7
+ require 'active_support/time'
8
+ require 'thinking_sphinx'
8
9
  require 'thinking_sphinx/deltas/datetime_delta'
9
10
 
10
- Spec::Runner.configure do |config|
11
+ RSpec.configure do |config|
11
12
  #
12
13
  end
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require './spec/spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Deltas::DatetimeDelta do
4
4
  before :each do
@@ -6,32 +6,34 @@ describe ThinkingSphinx::Deltas::DatetimeDelta do
6
6
  stub('index'), {}
7
7
  )
8
8
  end
9
-
9
+
10
10
  describe '#index' do
11
11
  it "should do nothing to the model" do
12
12
  @datetime_delta.index(stub('model'))
13
13
  end
14
-
14
+
15
15
  it "should do nothing to the instance, if provided" do
16
16
  @datetime_delta.index(stub('model'), stub('instance'))
17
17
  end
18
-
18
+
19
19
  it "should make no system calls" do
20
20
  @datetime_delta.stub! :` => true
21
21
  @datetime_delta.stub! :system => true
22
-
22
+
23
23
  @datetime_delta.should_not_receive(:`)
24
24
  @datetime_delta.should_not_receive(:system)
25
-
25
+
26
26
  @datetime_delta.index(stub('model'), stub('instance'))
27
27
  end
28
-
28
+
29
29
  it "should return true" do
30
30
  @datetime_delta.index(stub('model')).should be_true
31
31
  end
32
32
  end
33
-
33
+
34
34
  describe '#delayed_index' do
35
+ let(:root) { File.expand_path File.dirname(__FILE__) + '/../../..' }
36
+
35
37
  before :each do
36
38
  @index = stub('index',
37
39
  :delta? => true,
@@ -44,92 +46,100 @@ describe ThinkingSphinx::Deltas::DatetimeDelta do
44
46
  :delta_index_names => ['foo_delta'],
45
47
  :sphinx_indexes => [@index]
46
48
  )
47
-
49
+
48
50
  ThinkingSphinx.suppress_delta_output = false
49
-
51
+
50
52
  @datetime_delta.stub! :` => ""
51
53
  @datetime_delta.stub! :puts => nil
52
54
  end
53
-
55
+
54
56
  it "should process the delta index for the given model" do
55
57
  @datetime_delta.should_receive(:`).
56
- with('indexer --config /config/development.sphinx.conf foo_delta')
57
-
58
+ with("indexer --config /config/development.sphinx.conf foo_delta")
59
+
58
60
  @datetime_delta.delayed_index(@model)
59
61
  end
60
-
62
+
61
63
  it "should merge the core and delta indexes for the given model" do
62
- @datetime_delta.should_receive(:`).with('indexer --config /config/development.sphinx.conf --merge foo_core foo_delta --merge-dst-range sphinx_deleted 0 0')
63
-
64
+ @datetime_delta.should_receive(:`).with("indexer --config /config/development.sphinx.conf --merge foo_core foo_delta --merge-dst-range sphinx_deleted 0 0")
65
+
64
66
  @datetime_delta.delayed_index(@model)
65
67
  end
66
-
68
+
67
69
  it "should include --rotate if Sphinx is running" do
68
70
  ThinkingSphinx.stub!(:sphinx_running? => true)
69
71
  @datetime_delta.should_receive(:`) do |command|
70
72
  command.should match(/\s--rotate\s/)
73
+ 'output'
71
74
  end
72
-
75
+
73
76
  @datetime_delta.delayed_index(@model)
74
77
  end
75
-
78
+
76
79
  it "should output the details by default" do
77
80
  @datetime_delta.should_receive(:puts)
78
-
81
+
79
82
  @datetime_delta.delayed_index(@model)
80
83
  end
81
-
84
+
82
85
  it "should hide the details if suppressing delta output" do
83
86
  ThinkingSphinx.suppress_delta_output = true
84
87
  @datetime_delta.should_not_receive(:puts)
85
-
88
+
86
89
  @datetime_delta.delayed_index(@model)
87
90
  end
88
91
  end
89
-
92
+
90
93
  describe '#toggle' do
91
94
  it "should do nothing to the instance" do
92
95
  @datetime_delta.toggle(stub('instance'))
93
96
  end
94
97
  end
95
-
98
+
96
99
  describe '#toggled' do
97
100
  it "should return true if the column value is more recent than the threshold" do
98
101
  instance = stub('instance', :updated_at => 20.minutes.ago)
99
102
  @datetime_delta.threshold = 30.minutes
100
-
103
+
101
104
  @datetime_delta.toggled(instance).should be_true
102
105
  end
103
-
106
+
104
107
  it "should return false if the column value is older than the threshold" do
105
108
  instance = stub('instance', :updated_at => 30.minutes.ago)
106
109
  @datetime_delta.threshold = 20.minutes
107
-
110
+
111
+ @datetime_delta.toggled(instance).should be_false
112
+ end
113
+
114
+ it "should return false if the column value is null" do
115
+ instance = stub('instance', :updated_at => nil)
116
+ @datetime_delta.threshold = 20.minutes
117
+
108
118
  @datetime_delta.toggled(instance).should be_false
109
119
  end
110
120
  end
111
-
121
+
112
122
  describe '#reset_query' do
113
123
  it "should be nil" do
114
124
  @datetime_delta.reset_query(@model).should be_nil
115
125
  end
116
126
  end
117
-
127
+
118
128
  describe '#clause' do
119
129
  before :each do
120
130
  @model = stub('model', :connection => stub('connection'))
121
131
  @model.stub!(:quoted_table_name => '`foo`')
122
132
  @model.connection.stub!(:quote_column_name => '`updated_at`')
123
-
133
+
124
134
  @datetime_delta.stub!(
125
135
  :adapter => stub('adapter', :time_difference => 'time_difference')
126
136
  )
127
137
  end
128
-
138
+
129
139
  it "should return nil if not for the toggled results" do
130
140
  @datetime_delta.clause(@model, false).should be_nil
131
141
  end
132
-
142
+
133
143
  it "should return only records within the threshold" do
134
144
  @datetime_delta.clause(@model, true).
135
145
  should == '`foo`.`updated_at` > time_difference'
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ts-datetime-delta
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ hash: 17
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 3
10
+ version: 1.0.3
5
11
  platform: ruby
6
12
  authors:
7
13
  - Pat Allan
@@ -9,49 +15,68 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-12-03 00:00:00 +11:00
13
- default_executable:
18
+ date: 2012-06-11 00:00:00 Z
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: thinking-sphinx
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
20
25
  requirements:
21
26
  - - ">="
22
27
  - !ruby/object:Gem::Version
28
+ hash: 11
29
+ segments:
30
+ - 1
31
+ - 3
32
+ - 8
23
33
  version: 1.3.8
24
- version:
34
+ type: :runtime
35
+ version_requirements: *id001
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: rspec
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
30
41
  requirements:
31
42
  - - ">="
32
43
  - !ruby/object:Gem::Version
44
+ hash: 13
45
+ segments:
46
+ - 1
47
+ - 2
48
+ - 9
33
49
  version: 1.2.9
34
- version:
50
+ type: :development
51
+ version_requirements: *id002
35
52
  - !ruby/object:Gem::Dependency
36
53
  name: yard
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
40
57
  requirements:
41
58
  - - ">="
42
59
  - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
43
63
  version: "0"
44
- version:
64
+ type: :development
65
+ version_requirements: *id003
45
66
  - !ruby/object:Gem::Dependency
46
67
  name: cucumber
47
- type: :development
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
50
71
  requirements:
51
72
  - - ">="
52
73
  - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
53
77
  version: "0"
54
- version:
78
+ type: :development
79
+ version_requirements: *id004
55
80
  description: Manage delta indexes via datetime columns for Thinking Sphinx
56
81
  email: pat@freelancing-gods.com
57
82
  executables: []
@@ -66,44 +91,59 @@ files:
66
91
  - README.textile
67
92
  - lib/thinking_sphinx/deltas/datetime_delta.rb
68
93
  - lib/thinking_sphinx/deltas/datetime_delta/tasks.rb
69
- has_rdoc: true
94
+ - features/step_definitions/common_steps.rb
95
+ - features/step_definitions/datetime_delta_steps.rb
96
+ - features/support/db/fixtures/thetas.rb
97
+ - features/support/db/migrations/create_thetas.rb
98
+ - features/support/env.rb
99
+ - features/support/models/theta.rb
100
+ - features/datetime_deltas.feature
101
+ - features/support/database.example.yml
102
+ - spec/spec.opts
103
+ - spec/spec_helper.rb
104
+ - spec/thinking_sphinx/deltas/datetime_delta_spec.rb
70
105
  homepage: http://github.com/freelancing-god/ts-datetime-delta
71
106
  licenses: []
72
107
 
73
108
  post_install_message:
74
- rdoc_options:
75
- - --charset=UTF-8
109
+ rdoc_options: []
110
+
76
111
  require_paths:
77
112
  - lib
78
113
  required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
79
115
  requirements:
80
116
  - - ">="
81
117
  - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
120
+ - 0
82
121
  version: "0"
83
- version:
84
122
  required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
85
124
  requirements:
86
125
  - - ">="
87
126
  - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
88
130
  version: "0"
89
- version:
90
131
  requirements: []
91
132
 
92
133
  rubyforge_project:
93
- rubygems_version: 1.3.5
134
+ rubygems_version: 1.8.16
94
135
  signing_key:
95
136
  specification_version: 3
96
137
  summary: Thinking Sphinx - Datetime Deltas
97
138
  test_files:
98
- - features/datetime_deltas.feature
99
139
  - features/step_definitions/common_steps.rb
100
140
  - features/step_definitions/datetime_delta_steps.rb
101
- - features/support/database.example.yml
102
- - features/support/database.yml
103
141
  - features/support/db/fixtures/thetas.rb
104
142
  - features/support/db/migrations/create_thetas.rb
105
143
  - features/support/env.rb
106
144
  - features/support/models/theta.rb
145
+ - features/datetime_deltas.feature
146
+ - features/support/database.example.yml
107
147
  - spec/spec.opts
108
148
  - spec/spec_helper.rb
109
149
  - spec/thinking_sphinx/deltas/datetime_delta_spec.rb
@@ -1,5 +0,0 @@
1
- username: thinking_sphinx
2
- host: localhost
3
- password: thinking_sphinx
4
- pool: 1
5
- min_messages: warning