ts-datetime-delta 1.0.2 → 1.0.3

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.
@@ -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