taggable_cache 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ # rdoc generated
2
+ rdoc
3
+
4
+ # yard generated
5
+ doc
6
+ .yardoc
7
+
8
+ # bundler
9
+ .bundle
10
+
11
+ # jeweler generated
12
+ pkg
13
+
14
+ #fake app generated
15
+ /spec/internal/log
16
+ /spec/internal/db/*.sqlite
17
+ /tmp
data/.travis.yml ADDED
@@ -0,0 +1,2 @@
1
+ rvm:
2
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ end
8
+
9
+ gem 'rspec-rails', :require => false
10
+ gem 'rspec'
11
+ gem 'combustion', '~> 0.3.1'
12
+ gem 'sqlite3'
data/Gemfile.lock ADDED
@@ -0,0 +1,127 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ taggable_cache (0.1.0)
5
+ redis
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ actionmailer (3.2.1)
11
+ actionpack (= 3.2.1)
12
+ mail (~> 2.4.0)
13
+ actionpack (3.2.1)
14
+ activemodel (= 3.2.1)
15
+ activesupport (= 3.2.1)
16
+ builder (~> 3.0.0)
17
+ erubis (~> 2.7.0)
18
+ journey (~> 1.0.1)
19
+ rack (~> 1.4.0)
20
+ rack-cache (~> 1.1)
21
+ rack-test (~> 0.6.1)
22
+ sprockets (~> 2.1.2)
23
+ activemodel (3.2.1)
24
+ activesupport (= 3.2.1)
25
+ builder (~> 3.0.0)
26
+ activerecord (3.2.1)
27
+ activemodel (= 3.2.1)
28
+ activesupport (= 3.2.1)
29
+ arel (~> 3.0.0)
30
+ tzinfo (~> 0.3.29)
31
+ activeresource (3.2.1)
32
+ activemodel (= 3.2.1)
33
+ activesupport (= 3.2.1)
34
+ activesupport (3.2.1)
35
+ i18n (~> 0.6)
36
+ multi_json (~> 1.0)
37
+ arel (3.0.0)
38
+ builder (3.0.0)
39
+ coderay (0.9.8)
40
+ combustion (0.3.1)
41
+ rails (>= 3.1.0)
42
+ thor (>= 0.14.6)
43
+ diff-lcs (1.1.3)
44
+ erubis (2.7.0)
45
+ hike (1.2.1)
46
+ i18n (0.6.0)
47
+ journey (1.0.1)
48
+ json (1.6.5)
49
+ mail (2.4.1)
50
+ i18n (>= 0.4.0)
51
+ mime-types (~> 1.16)
52
+ treetop (~> 1.4.8)
53
+ method_source (0.6.7)
54
+ ruby_parser (>= 2.3.1)
55
+ mime-types (1.17.2)
56
+ multi_json (1.0.4)
57
+ polyglot (0.3.3)
58
+ pry (0.9.7.4)
59
+ coderay (~> 0.9.8)
60
+ method_source (~> 0.6.7)
61
+ ruby_parser (>= 2.3.1)
62
+ slop (~> 2.1.0)
63
+ rack (1.4.1)
64
+ rack-cache (1.1)
65
+ rack (>= 0.4)
66
+ rack-ssl (1.3.2)
67
+ rack
68
+ rack-test (0.6.1)
69
+ rack (>= 1.0)
70
+ rails (3.2.1)
71
+ actionmailer (= 3.2.1)
72
+ actionpack (= 3.2.1)
73
+ activerecord (= 3.2.1)
74
+ activeresource (= 3.2.1)
75
+ activesupport (= 3.2.1)
76
+ bundler (~> 1.0)
77
+ railties (= 3.2.1)
78
+ railties (3.2.1)
79
+ actionpack (= 3.2.1)
80
+ activesupport (= 3.2.1)
81
+ rack-ssl (~> 1.3.2)
82
+ rake (>= 0.8.7)
83
+ rdoc (~> 3.4)
84
+ thor (~> 0.14.6)
85
+ rake (0.9.2.2)
86
+ rdoc (3.12)
87
+ json (~> 1.4)
88
+ redis (2.2.2)
89
+ rspec (2.8.0)
90
+ rspec-core (~> 2.8.0)
91
+ rspec-expectations (~> 2.8.0)
92
+ rspec-mocks (~> 2.8.0)
93
+ rspec-core (2.8.0)
94
+ rspec-expectations (2.8.0)
95
+ diff-lcs (~> 1.1.2)
96
+ rspec-mocks (2.8.0)
97
+ rspec-rails (2.8.1)
98
+ actionpack (>= 3.0)
99
+ activesupport (>= 3.0)
100
+ railties (>= 3.0)
101
+ rspec (~> 2.8.0)
102
+ ruby_parser (2.3.1)
103
+ sexp_processor (~> 3.0)
104
+ sexp_processor (3.0.10)
105
+ slop (2.1.0)
106
+ sprockets (2.1.2)
107
+ hike (~> 1.2)
108
+ rack (~> 1.0)
109
+ tilt (~> 1.1, != 1.3.0)
110
+ sqlite3 (1.3.5)
111
+ thor (0.14.6)
112
+ tilt (1.3.3)
113
+ treetop (1.4.10)
114
+ polyglot
115
+ polyglot (>= 0.3.1)
116
+ tzinfo (0.3.31)
117
+
118
+ PLATFORMS
119
+ ruby
120
+
121
+ DEPENDENCIES
122
+ combustion (~> 0.3.1)
123
+ pry
124
+ rspec
125
+ rspec-rails
126
+ sqlite3
127
+ taggable_cache!
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Alex Rozumey
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.rdoc ADDED
@@ -0,0 +1,26 @@
1
+ = Taggable cache
2
+
3
+ This gem simplifies cache expiration in rails.
4
+
5
+ = How to use
6
+
7
+ See example in spec/internal.
8
+
9
+ == Build Status {<img src="https://secure.travis-ci.org/brain-geek/taggable-cache.png"/>}[http://travis-ci.org/brain-geek/taggable-cache]
10
+
11
+ == Dependency Status {<img src="https://gemnasium.com/brain-geek/taggable-cache.png?travis"/>}[https://gemnasium.com/brain-geek/taggable-cache]
12
+
13
+ == Contributing to taggable-cache
14
+
15
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
16
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
17
+ * Fork the project.
18
+ * Start a feature/bugfix branch.
19
+ * Commit and push until you are happy with your contribution.
20
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
21
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
22
+
23
+ == Copyright
24
+
25
+ Copyright (c) 2012 Alex Rozumey. See LICENSE.txt for further details.
26
+
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'bundler'
5
+ Bundler::GemHelper.install_tasks
6
+ rescue LoadError => e
7
+ warn "[WARNING]: It is recommended that you use bundler during development: gem install bundler"
8
+ end
9
+
10
+ require 'rspec/core/rake_task'
11
+
12
+ RSpec::Core::RakeTask.new('spec')
13
+
14
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/config.ru ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require :default, :development
5
+
6
+ Combustion.initialize!
7
+ run Combustion::Application
@@ -0,0 +1,4 @@
1
+ module TaggableCache
2
+ end
3
+
4
+ require 'taggable_cache/store'
@@ -0,0 +1,5 @@
1
+ module TaggableCache::Rails
2
+ end
3
+
4
+ require 'taggable_cache/rails/cache'
5
+ require 'taggable_cache/rails/observer'
@@ -0,0 +1,15 @@
1
+ module TaggableCache::Rails::Cache
2
+ def taggable
3
+ @taggable ||= ::TaggableCache::Store.new
4
+ end
5
+
6
+ def write(name, value, options = nil)
7
+ if options.has_key?(:depends_on)
8
+ taggable.add(name, *options[:depends_on])
9
+ #@taggable.
10
+ options.delete(:depends_on)
11
+ end
12
+
13
+ super(name, value, options)
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ class TaggableCache::Rails::Observer < ActiveRecord::Observer
2
+ def event(model)
3
+ Rails.cache.taggable.get(model, model.class).each do |m|
4
+ Rails.cache.delete(m)
5
+ end
6
+ end
7
+
8
+ alias :after_update :event
9
+ alias :after_destroy :event
10
+ alias :after_create :event
11
+ end
@@ -0,0 +1,37 @@
1
+ require "redis"
2
+
3
+ class TaggableCache::Store
4
+ def initialize
5
+ @redis = Redis.new
6
+ end
7
+
8
+ def id_for(obj)
9
+ if obj.is_a? Class
10
+ obj.to_s.downcase
11
+ elsif obj.is_a? ActiveRecord::Base
12
+ if obj.persisted?
13
+ "#{obj.class.to_s.downcase}-#{obj.id}"
14
+ else
15
+ id_for(obj.class)
16
+ end
17
+ else
18
+ nil
19
+ end
20
+ end
21
+
22
+ def add(tag, *members)
23
+ members.each do |element|
24
+ ident = id_for(element)
25
+ @redis.sadd ident, tag unless ident.nil?
26
+ end
27
+ end
28
+
29
+ def get(*members)
30
+ members.map do |tag|
31
+ ident = id_for(tag)
32
+ elements = @redis.smembers(ident)
33
+ @redis.del(ident)
34
+ elements
35
+ end.flatten.compact
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module TaggableCache
2
+ VERSION = "0.1.0" # This is for the gem and does not conflict with the rest of the functionality
3
+ end
@@ -0,0 +1,2 @@
1
+ class Page < ActiveRecord::Base
2
+ end
@@ -0,0 +1,3 @@
1
+ class SimpleObserver < TaggableCache::Rails::Observer
2
+ observe Page
3
+ end
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: db/combustion_test.sqlite
@@ -0,0 +1,11 @@
1
+ #combustion uses rails file cache, so we make magic on it
2
+ require 'taggable_cache/rails'
3
+
4
+ ActiveSupport::Cache::FileStore.class_eval do
5
+ include TaggableCache::Rails::Cache
6
+ end
7
+
8
+ #Listing all models with enabled taggable cache
9
+ # TaggableCache::Rails::Observer.observe Page
10
+
11
+ Combustion::Application.config.active_record.observers = :simple_observer
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ #
3
+ end
@@ -0,0 +1,7 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table(:pages, :force => true) do |t|
3
+ t.string :name
4
+ t.text :content
5
+ t.timestamps
6
+ end
7
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ describe Page do
4
+ end
@@ -0,0 +1,41 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
+
3
+ describe TaggableCache::Rails::Cache do
4
+ before :all do
5
+ @object = TaggableCache::Store.new
6
+ Redis.new.flushall
7
+
8
+ @page_object = Page.create
9
+ end
10
+
11
+ describe "taggable hooked on Rails.cache.write" do
12
+ it "adds key to store" do
13
+ Rails.cache.write 'key', 'value', :depends_on => [@page_object]
14
+
15
+ @object.get(@page_object).should == ['key']
16
+ end
17
+ end
18
+
19
+ describe "taggable hooked as observer" do
20
+ it "detects object change" do
21
+ Rails.cache.write 'key', 'value', :depends_on => [@page_object]
22
+
23
+ Rails.cache.read('key').should == 'value'
24
+
25
+ @page_object.name = @page_object.name.to_s + '1'
26
+ @page_object.save!
27
+
28
+ Rails.cache.read('key').should be_nil
29
+ end
30
+
31
+ it "detects model change" do
32
+ Rails.cache.write 'lorem', 'impsum', :depends_on => [Page]
33
+
34
+ Rails.cache.read('lorem').should == 'impsum'
35
+
36
+ Page.create
37
+
38
+ Rails.cache.read('lorem').should be_nil
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'taggable_cache'
4
+
5
+ Bundler.require :default, :development
6
+
7
+ Combustion.initialize!
8
+
9
+ require 'rspec/rails'
10
+
11
+ RSpec.configure do |config|
12
+ config.use_transactional_fixtures = true
13
+ end
@@ -0,0 +1,80 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ describe TaggableCache::Store do
4
+ describe "connection to redis" do
5
+ it "should use default settings" do
6
+ Redis.should_receive(:new)
7
+ TaggableCache::Store.new
8
+ end
9
+ end
10
+
11
+ describe "adding tags" do
12
+ before :all do
13
+ @object = TaggableCache::Store.new
14
+ @redis = Redis.new
15
+ #clean up all redis data
16
+ @redis.flushall
17
+ end
18
+
19
+ describe "queque names" do
20
+ it "should use id and model name if saved activerecord object" do
21
+ page = Page.create
22
+ @object.id_for(page).should == "page-#{page.id}"
23
+ end
24
+
25
+ it "should use id and model name if not saved activerecord object" do
26
+ @object.id_for(Page.new(:id => 1)).should == 'page'
27
+ end
28
+
29
+ it "should use model name if model is passed" do
30
+ @object.id_for(Page).should == 'page'
31
+ end
32
+
33
+ it "should return nil if unknown is passed" do
34
+ @object.id_for(123).should be_nil
35
+ end
36
+ end
37
+
38
+ describe "add data to redis" do
39
+ it "should push data" do
40
+ o1 = Object.new
41
+ o2 = Object.new
42
+
43
+ @object.should_receive(:id_for).with(o1).and_return('member1')
44
+ @object.should_receive(:id_for).with(o2).and_return('member2')
45
+ @object.should_receive(:id_for).with(nil).and_return(nil)
46
+
47
+ @object.add('tag_name', o1, nil, o2)
48
+
49
+ @redis.smembers(nil).should == []
50
+ @redis.smembers('member1').should == ['tag_name']
51
+ @redis.smembers('member2').should == ['tag_name']
52
+ end
53
+ end
54
+
55
+ describe "get data from redis" do
56
+ it "should return keys and leave nothing behind" do
57
+ page = Page.create
58
+
59
+ @object.add('tag_name', page)
60
+ @redis.smembers("page-#{page.id}").should == ['tag_name']
61
+
62
+ @object.get(page).should == ['tag_name']
63
+ @redis.smembers("page-#{page.id}").should be_empty
64
+ end
65
+
66
+ it "should do multi-get" do
67
+ page = Page.create
68
+
69
+ @object.add('tag_name', page)
70
+ @object.add('tag2', Page)
71
+ @redis.smembers("page-#{page.id}").should == ['tag_name']
72
+ @redis.smembers("page").should == ['tag2']
73
+
74
+ @object.get(page, Page).should == ['tag_name', 'tag2']
75
+ @redis.smembers("page-#{page.id}").should be_empty
76
+ @redis.smembers("page").should be_empty
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'rake'
4
+ $:.push File.expand_path("../lib", __FILE__)
5
+ require "taggable_cache/version"
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "taggable_cache"
9
+ s.version = TaggableCache::VERSION
10
+
11
+ s.authors = ["Alex Rozumey"]
12
+ s.date = "2012-02-09"
13
+ s.description = "This gem simplifies cache expiration in rails"
14
+ s.email = "brain-geek@yandex.ua"
15
+
16
+ s.extra_rdoc_files = [
17
+ "LICENSE.txt",
18
+ "README.rdoc"
19
+ ]
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+
26
+ s.homepage = "http://github.com/brain-geek/taggable-cache"
27
+ s.licenses = ["MIT"]
28
+ s.rubygems_version = "1.8.15"
29
+ s.summary = "This gem simplifies cache expiration in rails by providing depends_on option to rails cache."
30
+
31
+ s.add_dependency(%q<redis>, [">= 0"])
32
+ end
33
+
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: taggable_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex Rozumey
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: redis
16
+ requirement: &72590360 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *72590360
25
+ description: This gem simplifies cache expiration in rails
26
+ email: brain-geek@yandex.ua
27
+ executables: []
28
+ extensions: []
29
+ extra_rdoc_files:
30
+ - LICENSE.txt
31
+ - README.rdoc
32
+ files:
33
+ - .document
34
+ - .gitignore
35
+ - .travis.yml
36
+ - Gemfile
37
+ - Gemfile.lock
38
+ - LICENSE.txt
39
+ - README.rdoc
40
+ - Rakefile
41
+ - VERSION
42
+ - config.ru
43
+ - lib/taggable_cache.rb
44
+ - lib/taggable_cache/rails.rb
45
+ - lib/taggable_cache/rails/cache.rb
46
+ - lib/taggable_cache/rails/observer.rb
47
+ - lib/taggable_cache/store.rb
48
+ - lib/taggable_cache/version.rb
49
+ - spec/internal/app/models/page.rb
50
+ - spec/internal/app/models/simple_observer.rb
51
+ - spec/internal/config/database.yml
52
+ - spec/internal/config/initializers/taggable.rb
53
+ - spec/internal/config/routes.rb
54
+ - spec/internal/db/schema.rb
55
+ - spec/internal/public/favicon.ico
56
+ - spec/models/page_spec.rb
57
+ - spec/rails_cache_spec.rb
58
+ - spec/spec_helper.rb
59
+ - spec/taggable-cache/store_spec.rb
60
+ - taggable-cache.gemspec
61
+ homepage: http://github.com/brain-geek/taggable-cache
62
+ licenses:
63
+ - MIT
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ segments:
75
+ - 0
76
+ hash: 740775313
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ segments:
84
+ - 0
85
+ hash: 740775313
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 1.8.15
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: This gem simplifies cache expiration in rails by providing depends_on option
92
+ to rails cache.
93
+ test_files: []