ca_ching 0.1.0 → 0.1.1

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/.rvmrc ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
+ # Only full ruby name is supported here, for short names use:
8
+ # echo "rvm use 1.9.3" > .rvmrc
9
+ environment_id="ruby-1.9.3-p194@ca_ching"
10
+
11
+ # Uncomment the following lines if you want to verify rvm version per project
12
+ # rvmrc_rvm_version="1.14.5 (stable)" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+
18
+ # First we attempt to load the desired environment directly from the environment
19
+ # file. This is very fast and efficient compared to running through the entire
20
+ # CLI and selector. If you want feedback on which environment was used then
21
+ # insert the word 'use' after --create as this triggers verbose mode.
22
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
+ then
25
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
+ [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
+ \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
+ else
29
+ # If the environment file has not yet been created, use the RVM CLI to select.
30
+ rvm --create "$environment_id" || {
31
+ echo "Failed to create RVM environment '${environment_id}'."
32
+ return 1
33
+ }
34
+ fi
35
+
36
+ # If you use bundler, this might be useful to you:
37
+ # if [[ -s Gemfile ]] && {
38
+ # ! builtin command -v bundle >/dev/null ||
39
+ # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
40
+ # }
41
+ # then
42
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
43
+ # gem install bundler
44
+ # fi
45
+ # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
46
+ # then
47
+ # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
48
+ # fi
data/Gemfile CHANGED
@@ -3,14 +3,14 @@ source "http://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  # Development gems
6
- gem 'ruby-debug19'
6
+ gem 'debugger'
7
7
  gem 'rake'
8
8
 
9
- gem 'sqlite3'
9
+ gem 'sqlite3', '1.3.5'
10
10
 
11
11
  # Testing
12
12
  gem 'rspec'
13
13
  gem 'machinist'
14
14
  gem 'faker'
15
15
  gem 'guard-rspec'
16
- gem 'growl_notify'
16
+ gem 'growl'
data/README.md CHANGED
@@ -6,7 +6,10 @@ That means that when you read from the database, your results are stored in the
6
6
  the database, whatever is written to the database is also written to the cache (write-through). If the results are already
7
7
  in the cache, great, they're read straight from there on a read, and updated on a write.
8
8
 
9
- Take a look at `SPEC.md` for what's planned for v1.
9
+ This is definitely still alpha-level software. It's just something I thought should exist; I'm not using it in production
10
+ anywhere. It could blow up in totally unexpected, but nevertheless exciting, ways. If it does fall over, [let me know](http://github.com/ahlatimer/ca_ching/issues).
11
+
12
+ Take a look at `SPEC.md` for what's planned for v1.
10
13
 
11
14
  ## Getting started
12
15
 
@@ -50,9 +53,9 @@ miss and pull the data into the cache.
50
53
 
51
54
  ## Queries supported
52
55
 
53
- Generally anything `eqality` is supported by CaChing. Currently, only single fields can be found (e.g., `Person.where(:name => 'Andrew')` will be cached,
56
+ Generally anything involving equality is supported by CaChing. Currently, only single fields can be found (e.g., `Person.where(:name => 'Andrew')` will be cached,
54
57
  `Person.where(:name => 'Andrew', :age => 22)` is not). There is some plumbing for adding support for the latter, and support will be
55
- introduced as soon as possible.
58
+ introduced as soon as possible. I also have plans to add limited support for comparators (i.e., <, <=, >, >=).
56
59
 
57
60
  Anything including joins, includes, `OR`, and inequality (!=) are not supported, nor do I have any plans for adding support.
58
61
 
@@ -75,7 +78,7 @@ These queries are not:
75
78
 
76
79
  ### Order
77
80
 
78
- Order is not currently supported, although there will be some order semantics in the next version.
81
+ Order is not currently supported, although there will be some order functionality in the next version.
79
82
 
80
83
  ### Composite keys and queries against multiple fields
81
84
 
@@ -89,6 +92,12 @@ composite key *is* specified, CaChing will keep the resulting set.
89
92
  While there is support for this in the Redis adapter, there isn't any support in the ActiveRecord ties as I haven't
90
93
  decided how, exactly, I'd like to add this.
91
94
 
95
+ ### Thar be dragons
96
+
97
+ While I've tried to outline the issues here (and write failing specs for them), realize that this is
98
+ still very much alpha software. There are probably a number of unknown unknowns that I just haven't
99
+ uncovered yet. If you find them, please be sure to [let me know](http://github.com/ahlatimer/ca_ching/issues)!
100
+
92
101
  ## Ruby/Rails versions supported
93
102
 
94
103
  Ruby 1.9.2 and Rails 3.1+ are officially supported. I try to stick to Ruby 1.8.7 syntax, so it may be supported,
data/ca_ching.gemspec CHANGED
@@ -20,6 +20,6 @@ Gem::Specification.new do |s|
20
20
 
21
21
  s.add_dependency 'hiredis'
22
22
  s.add_dependency 'redis', '2.2.2'
23
- s.add_dependency 'activesupport', '>= 3.1.0'
24
- s.add_dependency 'activerecord', '>= 3.1.0'
23
+ s.add_dependency 'activesupport', '>= 3.2.0'
24
+ s.add_dependency 'activerecord', '>= 3.2.0'
25
25
  end
data/dump.rdb ADDED
Binary file
@@ -19,10 +19,8 @@ module CaChing
19
19
  end
20
20
  end
21
21
 
22
- module InstanceMethods
23
- def indexed_fields
24
- self.class.indexed_fields
25
- end
22
+ def indexed_fields
23
+ self.class.indexed_fields
26
24
  end
27
25
  end
28
- end
26
+ end
@@ -9,50 +9,49 @@ module CaChing
9
9
  module ClassMethods
10
10
  end
11
11
 
12
- module InstanceMethods
13
- # All queries, be they find(id), dynamic finders (find_by_foo, find_all_by_foo, etc.),
14
- # where(:foo => :bar), order('foo DESC'), etc. go through to_a before being returned.
15
- # Hook into that point to check the cache.
16
- def to_a_with_cache
17
- @_query = CaChing::Query::Select.new(self)
18
-
19
- return to_a_without_cache if CaChing.cache.nil? || CaChing.disabled? || !cacheable?
20
-
21
- result = CaChing.cache.find(@_query)
22
- @from_cache = true
23
-
24
- if result.nil?
25
- result = to_a_without_cache
26
- CaChing.cache.insert(result, :for => @_query)
27
- @from_cache = false
28
- end
29
-
30
- result.from_cache = self.from_cache?
31
- result.each { |item| item.from_cache = self.from_cache? }
32
-
33
- return result
34
- end
12
+ # All queries, be they find(id), dynamic finders (find_by_foo, find_all_by_foo, etc.),
13
+ # where(:foo => :bar), order('foo DESC'), etc. go through to_a before being returned.
14
+ # Hook into that point to check the cache.
15
+ def to_a_with_cache
16
+ @_query = CaChing::Query::Select.new(self)
35
17
 
36
- def from_cache?
37
- @from_cache ||= false
38
- end
18
+ return to_a_without_cache if CaChing.cache.nil? || CaChing.disabled? || !cacheable?
39
19
 
40
- def cacheable?
41
- unsupported_methods = [:from_value,
42
- :group_values,
43
- :having_values,
44
- :includes_values,
45
- :joined_includes_values,
46
- :joins_values,
47
- :lock_value,
48
- :select_values]
49
- !where_values.empty? && find_on_indexed_fields? && unsupported_methods.inject(true) { |flag, method| self.send(method).send(method.to_s =~ /values/ ? :empty? : :nil?) && flag }
50
- end
20
+ result = CaChing.cache.find(@_query)
21
+ @from_cache = true
51
22
 
52
- private
53
- def find_on_indexed_fields?
54
- (@_query.where.keys - indexed_fields.keys).empty?
23
+ if result.nil?
24
+ result = to_a_without_cache
25
+ CaChing.cache.insert(result, :for => @_query)
26
+ @from_cache = false
55
27
  end
28
+
29
+ result.from_cache = self.from_cache?
30
+ result.each { |item| item.from_cache = self.from_cache? }
31
+
32
+ return result
33
+ end
34
+
35
+ def from_cache?
36
+ @from_cache ||= false
37
+ end
38
+
39
+ def cacheable?
40
+ unsupported_methods = [:from_value,
41
+ :group_values,
42
+ :having_values,
43
+ :includes_values,
44
+ :joined_includes_values,
45
+ :joins_values,
46
+ :lock_value,
47
+ :select_values,
48
+ :order_values]
49
+ !where_values.empty? && find_on_indexed_fields? && unsupported_methods.inject(true) { |flag, method| self.send(method).send(method.to_s =~ /values/ ? :empty? : :nil?) && flag }
50
+ end
51
+
52
+ private
53
+ def find_on_indexed_fields?
54
+ (@_query.where.keys - indexed_fields.keys).empty?
56
55
  end
57
56
 
58
57
  included do |base|
@@ -61,4 +60,4 @@ module CaChing
61
60
  end
62
61
  end
63
62
  end
64
- end
63
+ end
@@ -2,7 +2,7 @@ module CaChing
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- PATCH = 0
5
+ PATCH = 1
6
6
  PRE = nil
7
7
 
8
8
 
@@ -5,19 +5,33 @@ module CaChing
5
5
  module ClassMethods
6
6
  end
7
7
 
8
- module InstanceMethods
9
- def save_with_cache(*)
10
- return save_without_cache if CaChing.cache.nil? || CaChing.disabled?
11
-
12
- CaChing.cache.update(self)
13
- save_without_cache
14
- end
8
+ def save_with_cache(*)
9
+ return save_without_cache if CaChing.cache.nil? || CaChing.disabled?
10
+
11
+ CaChing.cache.update(self)
12
+ save_without_cache
13
+ end
14
+
15
+ def save_with_cache!
16
+ return save_without_cache! if CaChing.cache.nil? || CaChing.disabled?
17
+
18
+ CaChing.cache.update(self)
19
+ save_without_cache!
15
20
  end
16
21
 
22
+ def destroy_with_cache(*)
23
+ return destroy_without_cache if CaChing.cache.nil? || CaChing.disabled?
24
+
25
+ CaChing.cache.destroy(self)
26
+ destroy_without_cache
27
+ end
28
+
17
29
  included do |base|
18
30
  base.class_eval do
19
31
  alias_method_chain :save, :cache
32
+ alias_method_chain :save!, :cache
33
+ alias_method_chain :destroy, :cache
20
34
  end
21
35
  end
22
36
  end
23
- end
37
+ end
@@ -99,7 +99,7 @@ module CaChing
99
99
  it 'handles multiple clauses' do
100
100
  ar = Person.where(:name => 'Andrew', :age => 22)
101
101
  query = Abstract.new(ar)
102
- query.where.should == { :name => ['=', 'Andrew'], :age => ['=', 22] }
102
+ query.where.should == { :name => ['=', 'Andrew'], :age => ['=', '22'] }
103
103
  end
104
104
  end
105
105
  end
@@ -192,4 +192,4 @@ module CaChing
192
192
  end
193
193
  end
194
194
  end
195
- end
195
+ end
@@ -11,15 +11,41 @@ module CaChing
11
11
  @cache.clear!
12
12
  end
13
13
 
14
- it 'updates the cache for a cached object' do
14
+ it 'updates the cache for a cached object with AR#save' do
15
15
  ar = Person.where(:id => 1)
16
16
  query = CaChing::Query::Abstract.new(ar)
17
17
  @cache.insert(ar.to_a_without_cache, :for => query)
18
18
 
19
- @person.name = @person.name.reverse
19
+ name = @person.name.reverse
20
+
21
+ @person.name = name
20
22
  @person.save
21
23
 
22
- @cache.find(CaChing::Query::Abstract.new(ar)).first.name.should == @person.name
24
+ @cache.find(CaChing::Query::Abstract.new(ar)).first.name.should == name
25
+ end
26
+
27
+ it 'updates the cache for a cached object with AR#save!' do
28
+ ar = Person.where(:id => 1)
29
+ query = CaChing::Query::Abstract.new(ar)
30
+ @cache.insert(ar.to_a_without_cache, :for => query)
31
+
32
+ name = @person.name.reverse
33
+
34
+ @person.name = name
35
+ @person.save!
36
+
37
+ @cache.find(CaChing::Query::Abstract.new(ar)).first.name.should == name
38
+ end
39
+
40
+ it 'updates the cache for a cached object with AR#update_attributes' do
41
+ ar = Person.where(:id => 1)
42
+ query = CaChing::Query::Abstract.new(ar)
43
+ @cache.insert(ar.to_a_without_cache, :for => query)
44
+
45
+ name = @person.name.reverse
46
+ @person.update_attributes(:name => name)
47
+
48
+ @cache.find(CaChing::Query::Abstract.new(ar)).first.name.should == name
23
49
  end
24
50
  end
25
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ca_ching
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
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: 2011-10-13 00:00:00.000000000Z
12
+ date: 2013-03-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: hiredis
16
- requirement: &2155697920 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,40 +21,60 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2155697920
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: redis
27
- requirement: &2155697420 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
- - - =
35
+ - - '='
31
36
  - !ruby/object:Gem::Version
32
37
  version: 2.2.2
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *2155697420
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.2.2
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: activesupport
38
- requirement: &2155696920 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
42
52
  - !ruby/object:Gem::Version
43
- version: 3.1.0
53
+ version: 3.2.0
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *2155696920
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.0
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: activerecord
49
- requirement: &2155696440 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
53
68
  - !ruby/object:Gem::Version
54
- version: 3.1.0
69
+ version: 3.2.0
55
70
  type: :runtime
56
71
  prerelease: false
57
- version_requirements: *2155696440
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 3.2.0
58
78
  description: Write-through ActiveRecord model caching that's right on the money
59
79
  email:
60
80
  - andrew@elpasoera.com
@@ -63,6 +83,7 @@ extensions: []
63
83
  extra_rdoc_files: []
64
84
  files:
65
85
  - .gitignore
86
+ - .rvmrc
66
87
  - Gemfile
67
88
  - Guardfile
68
89
  - LICENSE.txt
@@ -70,6 +91,7 @@ files:
70
91
  - Rakefile
71
92
  - SPEC.md
72
93
  - ca_ching.gemspec
94
+ - dump.rdb
73
95
  - lib/ca_ching.rb
74
96
  - lib/ca_ching/adapters/active_record.rb
75
97
  - lib/ca_ching/adapters/redis.rb
@@ -114,7 +136,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
136
  version: '0'
115
137
  segments:
116
138
  - 0
117
- hash: -832901543252096864
139
+ hash: 3771213621582903175
118
140
  required_rubygems_version: !ruby/object:Gem::Requirement
119
141
  none: false
120
142
  requirements:
@@ -123,10 +145,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
145
  version: '0'
124
146
  segments:
125
147
  - 0
126
- hash: -832901543252096864
148
+ hash: 3771213621582903175
127
149
  requirements: []
128
150
  rubyforge_project: ca_ching
129
- rubygems_version: 1.8.10
151
+ rubygems_version: 1.8.24
130
152
  signing_key:
131
153
  specification_version: 3
132
154
  summary: Write-through ActiveRecord model caching that's right on the money