memorize 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Roger Leite
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 NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,75 @@
1
+ h2. Memorize:
2
+
3
+ Allows Rails applications to do and control cache of actions.
4
+ With Memorize, you can expires your actions, calling a method in your model (or a CustomClass).
5
+ if you've suffered with Rails _caches_action_ and is tired of trying to expire your cache, Memorize is for you !
6
+ See below my 'code-explanation':
7
+
8
+ <pre>
9
+ <code>
10
+
11
+ class Article < ActiveRecord::Base
12
+ extend Memorize::Keys
13
+ [...]
14
+ end
15
+
16
+ class TestController < ApplicationController
17
+
18
+ #'classic' case of index, with categories, pagination and format support.
19
+ memorize_action :index, :key_builder => Article, :params => [:category, :page, :format]
20
+
21
+ #case of id, slug ... etc. Accessing a resource with identification.
22
+ memorize_action :show, :key_builder => Article, :key_param => :slug, :params => [:page, :format]
23
+
24
+ #case of 'custom' key, if you want to use a 'home made' solution. (here Memorize don't know how expires)
25
+ memorize_action :custom, :cache_path => lambda { |controller| "my_key" }
26
+
27
+ [...]
28
+ end
29
+
30
+ class ArticleSweeper < ActionController::Caching::Sweeper
31
+ observe Article
32
+ def after_save(article)
33
+ Article.cache_entries(:index).each { |key| Rails.cache.delete(key) }
34
+ Article.cache_entries(:show, :key => article.slug).each { |key| Rails.cache.delete(key) }
35
+
36
+ Rails.cache.delete("my_key") #Memorize does not handle custom keys
37
+ end
38
+ end
39
+
40
+ </pre>
41
+ </code>
42
+
43
+ h2. More
44
+
45
+ Memorize is designed to be simple and objetive.
46
+ Used and tested for *Rails 2.3.x*
47
+
48
+ h2. Install
49
+
50
+ Just execute:
51
+ <pre><code> sudo gem install memorize</code></pre>
52
+
53
+ And add to your environment.
54
+
55
+ *Important*: you can configure Memorize cache_store, adding a _memorize.rb_ to your _config/initializers_. Example:
56
+
57
+ <pre>
58
+ <code>
59
+ #Some examples to set Memorize cache_store:
60
+ Memorize.cache_store = Rails.cache
61
+ #Memorize.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
62
+ #Memorize.cache_store = ActiveSupport::Cache.lookup_store(:mem_cache_store, '127.0.0.1:11211')
63
+
64
+ #Your models can be 'Keys factories'
65
+ #ActiveRecord::Base.extend Memorize::Keys
66
+ </code>
67
+ </pre>
68
+
69
+ h2. Bugs and Feedback
70
+
71
+ If you find any issues, use Github issues tracker.
72
+
73
+ Copyright (c) 2010 Roger Leite
74
+ "1up4dev":http://1up4dev.org
75
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'rubygems/specification'
3
+ require 'rake'
4
+ require 'rake/gempackagetask'
5
+
6
+ GEM = "memorize"
7
+ GEM_VERSION = "0.1.0"
8
+ SUMMARY = "Allows Rails applications to do and control cache of actions"
9
+ AUTHOR = "Roger Leite"
10
+ EMAIL = "roger.barreto@gmail.com"
11
+ HOMEPAGE = "http://1up4dev.org"
12
+
13
+ spec = Gem::Specification.new do |s|
14
+ s.name = GEM
15
+ s.version = GEM_VERSION
16
+ s.platform = Gem::Platform::RUBY
17
+ s.summary = SUMMARY
18
+ s.require_paths = ['lib']
19
+ s.files = FileList['lib/**/*.rb', '[A-Z]*'].to_a
20
+
21
+ s.author = AUTHOR
22
+ s.email = EMAIL
23
+ s.homepage = HOMEPAGE
24
+ end
25
+
26
+ Rake::GemPackageTask.new(spec) do |pkg|
27
+ pkg.gem_spec = spec
28
+ end
29
+
30
+ desc "Install the gem locally"
31
+ task :install => [:package] do
32
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
33
+ end
34
+
35
+ desc "Create a gemspec file"
36
+ task :make_spec do
37
+ File.open("#{GEM}.gemspec", "w") do |file|
38
+ file.puts spec.to_ruby
39
+ end
40
+ end
41
+
42
+ require 'rake/testtask'
43
+ Rake::TestTask.new(:test) do |test|
44
+ test.test_files = FileList.new('test/**/test_*.rb') do |list|
45
+ list.exclude 'test/test_helper.rb'
46
+ end
47
+ test.libs << 'test'
48
+ test.verbose = true
49
+ end
@@ -0,0 +1,75 @@
1
+ module Memorize
2
+
3
+ # Exemplos de uso:
4
+ #
5
+ # class TestController < ApplicationController
6
+ # memorize_action :index, :key_builder => Article, :params => [:category, :page, :format]
7
+ # memorize_action :show, :key_builder => Article, :key_param => :slug, :params => [:page, :format]
8
+ # memorize_action :index, :cache_path => lambda { |controller| "my_key_#{controller.params.to_s}" }
9
+ # end
10
+
11
+ module Action
12
+
13
+ def memorize_action(*actions)
14
+ return unless self.perform_caching
15
+ options = actions.extract_options!
16
+ filter_options = { :only => actions, :if => options.delete(:if), :unless => options.delete(:unless) }
17
+
18
+ memorize_filter = MemorizeFilter.new(options)
19
+ around_filter(filter_options) do |controller, action|
20
+ memorize_filter.filter(controller, action)
21
+ end
22
+ end
23
+
24
+ class MemorizeFilter #:nodoc:
25
+
26
+ def initialize(options)
27
+ @cache_path = options.delete(:cache_path)
28
+ @key_builder = options.delete(:key_builder)
29
+ @key_param = options.delete(:key_param)
30
+ @key_params = options.delete(:params) || []
31
+ end
32
+
33
+ def filter(controller, action)
34
+ cache_path = eval_cache_path(controller)
35
+ cached = before(cache_path, controller)
36
+ unless cached
37
+ action.call
38
+ after(cache_path, controller) if caching_allowed?(controller)
39
+ end
40
+ end
41
+
42
+ def before(cache_path, controller)
43
+ if (cache = Memorize.cache_store.read(cache_path))
44
+ options = {:layout => false, :text => cache}
45
+ controller.__send__(:render, options)
46
+ end
47
+ !!cache
48
+ end
49
+
50
+ def after(cache_path, controller)
51
+ Memorize.cache_store.write cache_path, controller.response.body
52
+ end
53
+
54
+ private
55
+
56
+ def eval_cache_path(controller)
57
+ return @cache_path.call(controller) if @cache_path.respond_to?(:call)
58
+ unless @key_builder.respond_to?(:cache_key)
59
+ throw "Invalid 'key_builder' parameter. It should respond to 'cache_key' method."
60
+ end
61
+ group = controller.action_name.to_sym
62
+ key = controller.params[@key_param]
63
+ params = @key_params.collect { |param| controller.params[param] }
64
+ @key_builder.cache_key(group, :key => key, :params => params)
65
+ end
66
+
67
+ def caching_allowed?(controller)
68
+ controller.request.get? && controller.response.status.to_i == 200
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,52 @@
1
+ module Memorize
2
+
3
+ # Memorize padroniza e mantém as entradas associadas a um "grupo" e "key".
4
+ # Ao extender o Memorize::Keys, os seguintes métodos ficarão disponíveis:
5
+ #
6
+ # Model.cache_key(:group_id)
7
+ # Model.cache_key(:group_id, :key => "key")
8
+ #
9
+ # Model.cache_entries(:group_id)
10
+ # Model.cache_entries(:group_id, :key => "key")
11
+ module Keys
12
+
13
+ def cache_key(group, options = {})
14
+ param_key = options.delete(:key)
15
+ group_key = build_group_key(group, param_key)
16
+ cache_key = build_cache_key(group, param_key, options.delete(:params))
17
+ update_cache_entry(group_key, cache_key)
18
+ cache_key
19
+ end
20
+
21
+ def cache_entries(group, options = {})
22
+ group_key = build_group_key(group, options.delete(:key))
23
+ Memorize.cache_store.read(group_key) || []
24
+ end
25
+
26
+ private
27
+
28
+ def update_cache_entry(group_key, cache_key)
29
+ entries = (Memorize.cache_store.read(group_key) || [])
30
+ unless entries.include?(cache_key)
31
+ entries = entries.dup if entries.frozen?
32
+ entries << cache_key
33
+ Memorize.cache_store.write(group_key, entries)
34
+ end
35
+ end
36
+
37
+ def build_cache_key(group, key, *params)
38
+ cache_key = "#{self.to_s}/#{group.to_s}"
39
+ cache_key << "/#{key}" if key
40
+ params = params.flatten.compact
41
+ cache_key << "/#{params.join("/")}" unless params.blank?
42
+ cache_key
43
+ end
44
+
45
+ def build_group_key(group, key = nil)
46
+ group_key = "#{self.to_s}/keys/#{group.to_s}"
47
+ group_key << "/#{key}" if key
48
+ group_key
49
+ end
50
+ end
51
+
52
+ end
data/lib/memorize.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Memorize
2
+
3
+ class << self
4
+
5
+ def cache_store
6
+ @cache_store || ActiveSupport::Cache.lookup_store(:memory_store)
7
+ end
8
+
9
+ def cache_store=(cs)
10
+ @cache_store = cs
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+
17
+ require 'memorize/keys'
18
+ require 'memorize/action'
19
+
20
+ #add memorize_action to controllers
21
+ ActionController::Base.extend Memorize::Action
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: memorize
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Roger Leite
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-16 00:00:00 -03:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description:
22
+ email: roger.barreto@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/memorize/action.rb
31
+ - lib/memorize/keys.rb
32
+ - lib/memorize.rb
33
+ - README.textile
34
+ - MIT-LICENSE
35
+ - Rakefile
36
+ has_rdoc: true
37
+ homepage: http://1up4dev.org
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ segments:
50
+ - 0
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.6
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Allows Rails applications to do and control cache of actions
66
+ test_files: []
67
+