ts-datetime-delta 1.0.0
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/LICENSE +20 -0
- data/README.textile +50 -0
- data/features/datetime_deltas.feature +66 -0
- data/features/step_definitions/common_steps.rb +61 -0
- data/features/step_definitions/datetime_delta_steps.rb +15 -0
- data/features/support/database.example.yml +3 -0
- data/features/support/database.yml +5 -0
- data/features/support/db/fixtures/thetas.rb +10 -0
- data/features/support/db/migrations/create_thetas.rb +5 -0
- data/features/support/env.rb +17 -0
- data/features/support/models/theta.rb +7 -0
- data/lib/thinking_sphinx/deltas/datetime_delta.rb +124 -0
- data/lib/thinking_sphinx/deltas/datetime_delta/tasks.rb +23 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/thinking_sphinx/deltas/datetime_delta_spec.rb +130 -0
- metadata +99 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Pat Allan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
h1. Datetime Deltas for Thinking Sphinx
|
2
|
+
|
3
|
+
h2. Installation
|
4
|
+
|
5
|
+
You'll need Thinking Sphinx 1.3.0 or later.
|
6
|
+
|
7
|
+
<pre><code>gem install ts-datetime-delta --source http://gemcutter.org</code></pre>
|
8
|
+
|
9
|
+
In your @environment.rb@ file, with the rest of your gem dependencies:
|
10
|
+
|
11
|
+
<pre><code>config.gem 'ts-datetime-delta',
|
12
|
+
:lib => 'thinking_sphinx/deltas/datetime_delta'
|
13
|
+
:version => '>= 1.0.0',
|
14
|
+
:source => 'http://gemcutter.org'</code></pre>
|
15
|
+
|
16
|
+
And add the following line to the bottom of your @Rakefile@:
|
17
|
+
|
18
|
+
<pre><code>require 'thinking_sphinx/deltas/datetime_delta/tasks'</code></pre>
|
19
|
+
|
20
|
+
h2. Usage
|
21
|
+
|
22
|
+
For the indexes you want to use this delta approach, make sure you set that up in their @define_index@ blocks.
|
23
|
+
|
24
|
+
<pre><code>define_index do
|
25
|
+
# ...
|
26
|
+
|
27
|
+
set_property :delta => :datetime
|
28
|
+
end</code></pre>
|
29
|
+
|
30
|
+
If you want to use a column other than @updated_at@, you can specify it using the @:delta_column@ option. The same goes for the threshold, which defaults to one day.
|
31
|
+
|
32
|
+
<pre><code>set_property :delta => :datetime,
|
33
|
+
:threshold => 1.hour,
|
34
|
+
:delta_column => :changed_at</code></pre>
|
35
|
+
|
36
|
+
Then, while your Rails application is running, you'll need to run the delta indexing rake task regularly - as often as your threshold, allowing for some time for the indexing to actually happen.
|
37
|
+
|
38
|
+
For example, if you're going to run the delta indexing task every hour, I would recommend setting your threshold to 70 minutes.
|
39
|
+
|
40
|
+
To ensure this rake task is called regularly, it's best to set it up as a recurring task via cron or similar tools.
|
41
|
+
|
42
|
+
<pre><code>rake thinking_sphinx:index:delta</code></pre>
|
43
|
+
|
44
|
+
The shorthand version is:
|
45
|
+
|
46
|
+
<pre><code>rake ts:in:delta</code></pre>
|
47
|
+
|
48
|
+
h2. Copyright
|
49
|
+
|
50
|
+
Copyright (c) 2009 Pat Allan, and released under an MIT Licence.
|
@@ -0,0 +1,66 @@
|
|
1
|
+
Feature: Datetime Delta Indexing
|
2
|
+
In order to have delta indexing on frequently-updated sites
|
3
|
+
Developers
|
4
|
+
Should be able to use an existing datetime column to track changes
|
5
|
+
|
6
|
+
Scenario: Delta Index should not fire automatically
|
7
|
+
Given Sphinx is running
|
8
|
+
And I am searching on thetas
|
9
|
+
When I search for one
|
10
|
+
Then I should get 1 result
|
11
|
+
|
12
|
+
When I change the name of theta one to eleven
|
13
|
+
And I wait for Sphinx to catch up
|
14
|
+
And I search for one
|
15
|
+
Then I should get 1 result
|
16
|
+
|
17
|
+
When I search for eleven
|
18
|
+
Then I should get 0 results
|
19
|
+
|
20
|
+
Scenario: Delta Index should fire when jobs are run
|
21
|
+
Given Sphinx is running
|
22
|
+
And I am searching on thetas
|
23
|
+
When I search for two
|
24
|
+
Then I should get 1 result
|
25
|
+
|
26
|
+
When I change the name of theta two to twelve
|
27
|
+
And I wait for Sphinx to catch up
|
28
|
+
And I search for twelve
|
29
|
+
Then I should get 0 results
|
30
|
+
|
31
|
+
When I index the theta datetime delta
|
32
|
+
And I wait for Sphinx to catch up
|
33
|
+
And I search for twelve
|
34
|
+
Then I should get 1 result
|
35
|
+
|
36
|
+
When I search for two
|
37
|
+
Then I should get 0 results
|
38
|
+
|
39
|
+
Scenario: New records should be merged into the core index
|
40
|
+
Given Sphinx is running
|
41
|
+
And I am searching on thetas
|
42
|
+
When I search for thirteen
|
43
|
+
Then I should get 0 results
|
44
|
+
|
45
|
+
When I create a new theta named thirteen
|
46
|
+
And I search for thirteen
|
47
|
+
Then I should get 0 results
|
48
|
+
|
49
|
+
When I index the theta datetime delta
|
50
|
+
And I wait for Sphinx to catch up
|
51
|
+
And I search for thirteen
|
52
|
+
Then I should get 1 result
|
53
|
+
|
54
|
+
When I search for the document id of theta thirteen in the theta_core index
|
55
|
+
Then it should exist
|
56
|
+
|
57
|
+
Scenario: Deleting records
|
58
|
+
Given Sphinx is running
|
59
|
+
And I am searching on thetas
|
60
|
+
When I search for three
|
61
|
+
Then I should get 1 result
|
62
|
+
|
63
|
+
When I delete the theta named three
|
64
|
+
And I wait for Sphinx to catch up
|
65
|
+
And I search for three
|
66
|
+
Then I should get 0 results
|
@@ -0,0 +1,61 @@
|
|
1
|
+
Before do
|
2
|
+
$queries_executed = []
|
3
|
+
|
4
|
+
@model = nil
|
5
|
+
@method = :search
|
6
|
+
@query = ""
|
7
|
+
@conditions = {}
|
8
|
+
@with = {}
|
9
|
+
@without = {}
|
10
|
+
@with_all = {}
|
11
|
+
@options = {}
|
12
|
+
@results = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
Given "Sphinx is running" do
|
16
|
+
ThinkingSphinx::Configuration.instance.controller.should be_running
|
17
|
+
end
|
18
|
+
|
19
|
+
Given /^I am searching on (.+)$/ do |model|
|
20
|
+
@model = model.gsub(/\s/, '_').singularize.camelize.constantize
|
21
|
+
end
|
22
|
+
|
23
|
+
When "I wait for Sphinx to catch up" do
|
24
|
+
sleep(0.25)
|
25
|
+
end
|
26
|
+
|
27
|
+
When /^I search for (\w+)$/ do |query|
|
28
|
+
@results = nil
|
29
|
+
@query = query
|
30
|
+
end
|
31
|
+
|
32
|
+
When /^I search for the document id of (\w+) (\w+) in the (\w+) index$/ do |model, name, index|
|
33
|
+
model = model.gsub(/\s/, '_').camelize.constantize
|
34
|
+
@id = model.find_by_name(name).sphinx_document_id
|
35
|
+
@index = index
|
36
|
+
end
|
37
|
+
|
38
|
+
Then /^I should get (\d+) results?$/ do |count|
|
39
|
+
results.length.should == count.to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
Then "it should exist" do
|
43
|
+
ThinkingSphinx::Search.search_for_id(@id, @index).should == true
|
44
|
+
end
|
45
|
+
|
46
|
+
Then "it should not exist" do
|
47
|
+
ThinkingSphinx::Search.search_for_id(@id, @index).should == false
|
48
|
+
end
|
49
|
+
|
50
|
+
def results
|
51
|
+
@results ||= (@model || ThinkingSphinx).send(
|
52
|
+
@method,
|
53
|
+
@query,
|
54
|
+
@options.merge(
|
55
|
+
:conditions => @conditions,
|
56
|
+
:with => @with,
|
57
|
+
:without => @without,
|
58
|
+
:with_all => @with_all
|
59
|
+
)
|
60
|
+
)
|
61
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
When /^I index the theta datetime delta$/ do
|
2
|
+
Theta.sphinx_indexes.first.delta_object.delayed_index(Theta)
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I change the name of theta (\w+) to (\w+)$/ do |current, replacement|
|
6
|
+
Theta.find_by_name(current).update_attributes(:name => replacement)
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I create a new theta named (\w+)$/ do |name|
|
10
|
+
Theta.create(:name => name)
|
11
|
+
end
|
12
|
+
|
13
|
+
When /^I delete the theta named (\w+)$/ do |name|
|
14
|
+
Theta.find_by_name(name).destroy
|
15
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Theta.create :name => "one"
|
2
|
+
Theta.create :name => "two"
|
3
|
+
Theta.create :name => "three"
|
4
|
+
Theta.create :name => "four"
|
5
|
+
Theta.create :name => "five"
|
6
|
+
Theta.create :name => "six"
|
7
|
+
Theta.create :name => "seven"
|
8
|
+
Theta.create :name => "eight"
|
9
|
+
Theta.create :name => "nine"
|
10
|
+
Theta.create :name => "ten"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'cucumber'
|
3
|
+
require 'spec/expectations'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'active_record'
|
6
|
+
|
7
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
8
|
+
|
9
|
+
require 'cucumber/thinking_sphinx/internal_world'
|
10
|
+
|
11
|
+
world = Cucumber::ThinkingSphinx::InternalWorld.new
|
12
|
+
world.configure_database
|
13
|
+
|
14
|
+
require 'thinking_sphinx'
|
15
|
+
require 'thinking_sphinx/deltas/datetime_delta'
|
16
|
+
|
17
|
+
world.setup
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# Datetime Deltas for Thinking Sphinx
|
2
|
+
#
|
3
|
+
# This documentation is aimed at those reading the code. If you're looking for
|
4
|
+
# a guide to Thinking Sphinx and/or deltas, I recommend you start with the
|
5
|
+
# Thinking Sphinx site instead - or the README for this library at the very
|
6
|
+
# least.
|
7
|
+
#
|
8
|
+
# @author Patrick Allan
|
9
|
+
# @see http://ts.freelancing-gods.com Thinking Sphinx
|
10
|
+
#
|
11
|
+
class ThinkingSphinx::Deltas::DatetimeDelta < ThinkingSphinx::Deltas::DefaultDelta
|
12
|
+
attr_accessor :column, :threshold
|
13
|
+
|
14
|
+
# Initialises the Delta object for the given index and settings. All handled
|
15
|
+
# by Thinking Sphinx, so you shouldn't need to call this method yourself in
|
16
|
+
# general day-to-day situations.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# ThinkingSphinx::Deltas::DatetimeDelta.new index,
|
20
|
+
# :delta_column => :updated_at,
|
21
|
+
# :threshold => 1.day
|
22
|
+
#
|
23
|
+
# @param [ThinkingSphinx::Index] index the index using this delta object
|
24
|
+
# @param [Hash] options a hash of options for the index
|
25
|
+
# @option options [Symbol] :delta_column (:updated_at) The column to use for
|
26
|
+
# tracking when a record has changed. Default to :updated_at.
|
27
|
+
# @option options [Integer] :threshold (1.day) The window of time to store
|
28
|
+
# changes for, in seconds. Defaults to one day.
|
29
|
+
#
|
30
|
+
def initialize(index, options = {})
|
31
|
+
@index = index
|
32
|
+
@column = options.delete(:delta_column) || :updated_at
|
33
|
+
@threshold = options.delete(:threshold) || 1.day
|
34
|
+
end
|
35
|
+
|
36
|
+
# Does absolutely nothing, beyond returning true. Thinking Sphinx expects
|
37
|
+
# this method, though, and we don't want to use the inherited behaviour from
|
38
|
+
# DefaultDelta.
|
39
|
+
#
|
40
|
+
# All the real indexing logic is done by the delayed_index method.
|
41
|
+
#
|
42
|
+
# @param [Class] model the ActiveRecord model to index.
|
43
|
+
# @param [ActiveRecord::Base] instance the instance of the given model that
|
44
|
+
# has changed. Optional.
|
45
|
+
# @return [Boolean] true
|
46
|
+
# @see #delayed_index
|
47
|
+
#
|
48
|
+
def index(model, instance = nil)
|
49
|
+
# do nothing
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
# Processes the delta index for the given model, and then merges the relevant
|
54
|
+
# core and delta indexes together. By default, the output of these indexer
|
55
|
+
# commands are printed to stdout. If you'd rather it didn't, set
|
56
|
+
# ThinkingSphinx.suppress_delta_output to true.
|
57
|
+
#
|
58
|
+
# @param [Class] model the ActiveRecord model to index
|
59
|
+
# @return [Boolean] true
|
60
|
+
#
|
61
|
+
def delayed_index(model)
|
62
|
+
config = ThinkingSphinx::Configuration.instance
|
63
|
+
rotate = ThinkingSphinx.sphinx_running? ? " --rotate" : ""
|
64
|
+
|
65
|
+
output = `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file}#{rotate} #{delta_index_name model}`
|
66
|
+
output += `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file}#{rotate} --merge #{core_index_name model} #{delta_index_name model} --merge-dst-range sphinx_deleted 0 0`
|
67
|
+
puts output unless ThinkingSphinx.suppress_delta_output?
|
68
|
+
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
# Toggles the given instance to be flagged as part of the next delta indexing.
|
73
|
+
# For datetime deltas, this means do nothing at all.
|
74
|
+
#
|
75
|
+
# @param [ActiveRecord::Base] instance the instance to be toggled
|
76
|
+
#
|
77
|
+
def toggle(instance)
|
78
|
+
# do nothing
|
79
|
+
end
|
80
|
+
|
81
|
+
# Report whether a given instance is considered toggled (part of the next
|
82
|
+
# delta process). For datetime deltas, this is true if the delta column
|
83
|
+
# (updated_at by default) has a value within the threshold. Otherwise, false
|
84
|
+
# is returned.
|
85
|
+
#
|
86
|
+
# @param [ActiveRecord::Base] instance the instance to check
|
87
|
+
# @return [Boolean] True if within the threshold window, otherwise false.
|
88
|
+
#
|
89
|
+
def toggled(instance)
|
90
|
+
instance.send(@column) > @threshold.ago
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the SQL query that resets the model data after a normal index. For
|
94
|
+
# datetime deltas, nothing needs to be done, so this method returns nil.
|
95
|
+
#
|
96
|
+
# @param [Class] model The ActiveRecord model that is requesting the query
|
97
|
+
# @return [NilClass] Always nil
|
98
|
+
#
|
99
|
+
def reset_query(model)
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
|
103
|
+
# A SQL condition (as part of the WHERE clause) that limits the result set to
|
104
|
+
# just the delta data, or all data, depending on whether the toggled argument
|
105
|
+
# is true or not. For datetime deltas, the former value is a check on the
|
106
|
+
# delta column being within the threshold. In the latter's case, no condition
|
107
|
+
# is needed, so nil is returned.
|
108
|
+
#
|
109
|
+
# @param [Class] model The ActiveRecord model to generate the SQL condition
|
110
|
+
# for.
|
111
|
+
# @param [Boolean] toggled Whether the query should request delta documents or
|
112
|
+
# all documents.
|
113
|
+
# @return [String, NilClass] The SQL condition if the toggled version is
|
114
|
+
# requested, otherwise nil.
|
115
|
+
#
|
116
|
+
def clause(model, toggled)
|
117
|
+
if toggled
|
118
|
+
"#{model.quoted_table_name}.#{model.connection.quote_column_name(@column.to_s)}" +
|
119
|
+
" > #{adapter.time_difference(@threshold)}"
|
120
|
+
else
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
namespace :thinking_sphinx do
|
2
|
+
namespace :index do
|
3
|
+
desc "Index Thinking Sphinx datetime delta indexes"
|
4
|
+
task :delta => :app_env do
|
5
|
+
ThinkingSphinx.indexed_models.select { |model|
|
6
|
+
model.constantize.sphinx_indexes.any? { |index| index.delta? }
|
7
|
+
}.each do |model|
|
8
|
+
model.constantize.sphinx_indexes.select { |index|
|
9
|
+
index.delta? && index.delta_object.respond_to?(:delayed_index)
|
10
|
+
}.each { |index|
|
11
|
+
index.delta_object.delayed_index(index.model)
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
namespace :ts do
|
19
|
+
namespace :in do
|
20
|
+
desc "Index Thinking Sphinx datetime delta indexes"
|
21
|
+
task :delta => "thinking_sphinx:index:delta"
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
|
7
|
+
require 'thinking_sphinx'
|
8
|
+
require 'thinking_sphinx/deltas/delayed_delta'
|
9
|
+
|
10
|
+
Spec::Runner.configure do |config|
|
11
|
+
#
|
12
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe ThinkingSphinx::Deltas::DatetimeDelta do
|
4
|
+
before :each do
|
5
|
+
@datetime_delta = ThinkingSphinx::Deltas::DatetimeDelta.new(
|
6
|
+
stub('index'), {}
|
7
|
+
)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#index' do
|
11
|
+
it "should do nothing to the model" do
|
12
|
+
@datetime_delta.index(stub('model'))
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should do nothing to the instance, if provided" do
|
16
|
+
@datetime_delta.index(stub('model'), stub('instance'))
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should make no system calls" do
|
20
|
+
@datetime_delta.stub! :` => true
|
21
|
+
@datetime_delta.stub! :system => true
|
22
|
+
|
23
|
+
@datetime_delta.should_not_receive(:`)
|
24
|
+
@datetime_delta.should_not_receive(:system)
|
25
|
+
|
26
|
+
@datetime_delta.index(stub('model'), stub('instance'))
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return true" do
|
30
|
+
@datetime_delta.index(stub('model')).should be_true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#delayed_index' do
|
35
|
+
before :each do
|
36
|
+
@model = stub('foo')
|
37
|
+
@model.stub!(:name => 'foo')
|
38
|
+
@model.stub!(:source_of_sphinx_index => @model)
|
39
|
+
|
40
|
+
ThinkingSphinx.suppress_delta_output = false
|
41
|
+
|
42
|
+
@datetime_delta.stub! :` => ""
|
43
|
+
@datetime_delta.stub! :puts => nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should process the delta index for the given model" do
|
47
|
+
@datetime_delta.should_receive(:`).
|
48
|
+
with('indexer --config /config/development.sphinx.conf foo_delta')
|
49
|
+
|
50
|
+
@datetime_delta.delayed_index(@model)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should merge the core and delta indexes for the given model" do
|
54
|
+
@datetime_delta.should_receive(:`).with('indexer --config /config/development.sphinx.conf --merge foo_core foo_delta --merge-dst-range sphinx_deleted 0 0')
|
55
|
+
|
56
|
+
@datetime_delta.delayed_index(@model)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should include --rotate if Sphinx is running" do
|
60
|
+
ThinkingSphinx.stub!(:sphinx_running? => true)
|
61
|
+
@datetime_delta.should_receive(:`) do |command|
|
62
|
+
command.should match(/\s--rotate\s/)
|
63
|
+
end
|
64
|
+
|
65
|
+
@datetime_delta.delayed_index(@model)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should output the details by default" do
|
69
|
+
@datetime_delta.should_receive(:puts)
|
70
|
+
|
71
|
+
@datetime_delta.delayed_index(@model)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should hide the details if suppressing delta output" do
|
75
|
+
ThinkingSphinx.suppress_delta_output = true
|
76
|
+
@datetime_delta.should_not_receive(:puts)
|
77
|
+
|
78
|
+
@datetime_delta.delayed_index(@model)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#toggle' do
|
83
|
+
it "should do nothing to the instance" do
|
84
|
+
@datetime_delta.toggle(stub('instance'))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#toggled' do
|
89
|
+
it "should return true if the column value is more recent than the threshold" do
|
90
|
+
instance = stub('instance', :updated_at => 20.minutes.ago)
|
91
|
+
@datetime_delta.threshold = 30.minutes
|
92
|
+
|
93
|
+
@datetime_delta.toggled(instance).should be_true
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should return false if the column value is older than the threshold" do
|
97
|
+
instance = stub('instance', :updated_at => 30.minutes.ago)
|
98
|
+
@datetime_delta.threshold = 20.minutes
|
99
|
+
|
100
|
+
@datetime_delta.toggled(instance).should be_false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '#reset_query' do
|
105
|
+
it "should be nil" do
|
106
|
+
@datetime_delta.reset_query(@model).should be_nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#clause' do
|
111
|
+
before :each do
|
112
|
+
@model = stub('model', :connection => stub('connection'))
|
113
|
+
@model.stub!(:quoted_table_name => '`foo`')
|
114
|
+
@model.connection.stub!(:quote_column_name => '`updated_at`')
|
115
|
+
|
116
|
+
@datetime_delta.stub!(
|
117
|
+
:adapter => stub('adapter', :time_difference => 'time_difference')
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should return nil if not for the toggled results" do
|
122
|
+
@datetime_delta.clause(@model, false).should be_nil
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should return only records within the threshold" do
|
126
|
+
@datetime_delta.clause(@model, true).
|
127
|
+
should == '`foo`.`updated_at` > time_difference'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ts-datetime-delta
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pat Allan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-03 00:00:00 +11:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.9
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: yard
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: cucumber
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description: Manage delta indexes via datetime columns for Thinking Sphinx
|
46
|
+
email: pat@freelancing-gods.com
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files:
|
52
|
+
- LICENSE
|
53
|
+
- README.textile
|
54
|
+
files:
|
55
|
+
- LICENSE
|
56
|
+
- README.textile
|
57
|
+
- lib/thinking_sphinx/deltas/datetime_delta.rb
|
58
|
+
- lib/thinking_sphinx/deltas/datetime_delta/tasks.rb
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/freelancing-god/ts-datetime-delta
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options:
|
65
|
+
- --charset=UTF-8
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.3.5
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: Thinking Sphinx - Datetime Deltas
|
87
|
+
test_files:
|
88
|
+
- features/datetime_deltas.feature
|
89
|
+
- features/step_definitions/common_steps.rb
|
90
|
+
- features/step_definitions/datetime_delta_steps.rb
|
91
|
+
- features/support/database.example.yml
|
92
|
+
- features/support/database.yml
|
93
|
+
- features/support/db/fixtures/thetas.rb
|
94
|
+
- features/support/db/migrations/create_thetas.rb
|
95
|
+
- features/support/env.rb
|
96
|
+
- features/support/models/theta.rb
|
97
|
+
- spec/spec.opts
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
- spec/thinking_sphinx/deltas/datetime_delta_spec.rb
|