memorize 0.1.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/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
+