sequel-cacheable 0.0.7 → 1.0.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/.gitignore +53 -0
- data/.pryrc +17 -0
- data/.rbenv-version +1 -0
- data/.travis.yml +4 -1
- data/Gemfile +21 -23
- data/Procfile +2 -0
- data/README.rdoc +4 -3
- data/Rakefile +1 -36
- data/lib/sequel-cacheable/class_methods.rb +74 -0
- data/lib/sequel-cacheable/dataset_methods.rb +53 -0
- data/lib/sequel-cacheable/driver/dalli.rb +19 -0
- data/lib/sequel-cacheable/driver/memcache.rb +15 -0
- data/lib/sequel-cacheable/driver/redis.rb +6 -0
- data/lib/sequel-cacheable/driver.rb +56 -0
- data/lib/sequel-cacheable/instance_methods.rb +66 -0
- data/lib/sequel-cacheable/packer.rb +34 -0
- data/lib/sequel-cacheable/version.rb +7 -0
- data/lib/sequel-cacheable.rb +18 -211
- data/sequel-cacheable.gemspec +18 -94
- data/spec/lib/sequel-cacheable/driver/dalli_driver_spec.rb +8 -0
- data/spec/lib/sequel-cacheable/driver/memcache_driver_spec.rb +7 -0
- data/spec/lib/sequel-cacheable/driver/redis_driver_spec.rb +8 -0
- data/spec/lib/sequel-cacheable/driver_spec.rb +35 -0
- data/spec/lib/sequel-cacheable_spec.rb +1 -243
- data/spec/models/dalli_spec.rb +5 -0
- data/spec/models/memcache_spec.rb +5 -0
- data/spec/models/redis_spec.rb +5 -0
- data/spec/shared/cacheable.rb +161 -0
- data/spec/shared/driver.rb +102 -0
- data/spec/spec_helper.rb +25 -28
- data/spec/support/models/dalli.rb +5 -0
- data/spec/support/models/memcache.rb +5 -0
- data/spec/support/models/redis.rb +5 -0
- metadata +57 -241
- data/Gemfile.lock +0 -66
- data/VERSION +0 -1
    
        data/.gitignore
    ADDED
    
    | @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            # rcov generated
         | 
| 2 | 
            +
            coverage
         | 
| 3 | 
            +
            coverage.data
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # rdoc generated
         | 
| 6 | 
            +
            rdoc
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            # yard generated
         | 
| 9 | 
            +
            doc
         | 
| 10 | 
            +
            .yardoc
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            # bundler
         | 
| 13 | 
            +
            .bundle
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            # jeweler generated
         | 
| 16 | 
            +
            pkg
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            Gemfile.lock
         | 
| 19 | 
            +
            dump.rdb
         | 
| 20 | 
            +
            tmp
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
         | 
| 23 | 
            +
            #
         | 
| 24 | 
            +
            # * Create a file at ~/.gitignore
         | 
| 25 | 
            +
            # * Include files you want ignored
         | 
| 26 | 
            +
            # * Run: git config --global core.excludesfile ~/.gitignore
         | 
| 27 | 
            +
            #
         | 
| 28 | 
            +
            # After doing this, these files will be ignored in all your git projects,
         | 
| 29 | 
            +
            # saving you from having to 'pollute' every project you touch with them
         | 
| 30 | 
            +
            #
         | 
| 31 | 
            +
            # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
         | 
| 32 | 
            +
            #
         | 
| 33 | 
            +
            # For MacOS:
         | 
| 34 | 
            +
            #
         | 
| 35 | 
            +
            #.DS_Store
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            # For TextMate
         | 
| 38 | 
            +
            #*.tmproj
         | 
| 39 | 
            +
            #tmtags
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            # For emacs:
         | 
| 42 | 
            +
            #*~
         | 
| 43 | 
            +
            #\#*
         | 
| 44 | 
            +
            #.\#*
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            # For vim:
         | 
| 47 | 
            +
            #*.swp
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            # For redcar:
         | 
| 50 | 
            +
            #.redcar
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            # For rubinius:
         | 
| 53 | 
            +
            #*.rbc
         | 
    
        data/.pryrc
    ADDED
    
    | @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            require 'bundler'
         | 
| 3 | 
            +
            Bundler.require(:default, :development)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            $: << "#{Dir.pwd}/lib"
         | 
| 6 | 
            +
            require 'sequel-cacheable'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            DB = Sequel.sqlite
         | 
| 9 | 
            +
            DB.create_table(:mock) do
         | 
| 10 | 
            +
              primary_key :id, :auto_increment => true
         | 
| 11 | 
            +
              String :name
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            require 'memcache/null_server'
         | 
| 15 | 
            +
            class Mock < Sequel::Model(:mock)
         | 
| 16 | 
            +
              plugin :cacheable, Redis.new(server: 'localhost:6379'), :query_cache => true
         | 
| 17 | 
            +
            end
         | 
    
        data/.rbenv-version
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            1.9.3-p327
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/Gemfile
    CHANGED
    
    | @@ -1,30 +1,28 @@ | |
| 1 | 
            -
            source  | 
| 2 | 
            -
            # Add dependencies required to use your gem here.
         | 
| 3 | 
            -
            # Example:
         | 
| 4 | 
            -
            #   gem "activesupport", ">= 2.3.5"
         | 
| 1 | 
            +
            source :rubygems
         | 
| 5 2 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 3 | 
            +
            gem 'bundler'
         | 
| 4 | 
            +
            gem 'rake'
         | 
| 8 5 |  | 
| 9 | 
            -
             | 
| 10 | 
            -
            gem 'msgpack', '~> 0.4.6'
         | 
| 11 | 
            -
            gem 'hashr', '~> 0.0.19'
         | 
| 6 | 
            +
            gemspec
         | 
| 12 7 |  | 
| 13 8 | 
             
            group :development, :test do
         | 
| 14 | 
            -
              gem  | 
| 9 | 
            +
              gem 'rspec', "~> 2.12.0"
         | 
| 10 | 
            +
              gem 'yard', "~> 0.8.3"
         | 
| 11 | 
            +
              gem 'rdoc', "~> 3.12"
         | 
| 12 | 
            +
              gem 'simplecov', "~> 0.7.1", :require => false
         | 
| 15 13 |  | 
| 16 | 
            -
              gem  | 
| 17 | 
            -
              gem  | 
| 18 | 
            -
              gem  | 
| 19 | 
            -
              gem  | 
| 20 | 
            -
              gem 'simplecov', "~> 0.6.1", :require => false
         | 
| 14 | 
            +
              gem 'guard', '~> 1.6.1'
         | 
| 15 | 
            +
              gem 'guard-rspec', '~> 2.3.3'
         | 
| 16 | 
            +
              gem 'terminal-notifier'
         | 
| 17 | 
            +
              gem 'listen', '~> 0.7.0'
         | 
| 21 18 |  | 
| 22 | 
            -
              gem  | 
| 23 | 
            -
              gem  | 
| 24 | 
            -
              gem  | 
| 25 | 
            -
             | 
| 26 | 
            -
              gem  | 
| 27 | 
            -
              gem  | 
| 28 | 
            -
              gem  | 
| 29 | 
            -
              gem  | 
| 19 | 
            +
              gem 'sqlite3'
         | 
| 20 | 
            +
              gem 'dalli'
         | 
| 21 | 
            +
              gem 'memcache'
         | 
| 22 | 
            +
              gem 'hiredis'
         | 
| 23 | 
            +
              gem 'redis', :require => ['redis', 'redis/connection/hiredis']
         | 
| 24 | 
            +
              gem 'pry'
         | 
| 25 | 
            +
              gem 'pry-doc'
         | 
| 26 | 
            +
              gem 'forgery'
         | 
| 27 | 
            +
              gem 'tapp'
         | 
| 30 28 | 
             
            end
         | 
    
        data/Procfile
    ADDED
    
    
    
        data/README.rdoc
    CHANGED
    
    | @@ -23,15 +23,16 @@ Caching! | |
| 23 23 | 
             
            tested cache_client:
         | 
| 24 24 |  | 
| 25 25 | 
             
            * Redis[https://rubygems.org/gems/redis]
         | 
| 26 | 
            +
            * Hiredis[https://rubygems.org/gems/hiredis]
         | 
| 26 27 | 
             
            * Memcached[https://rubygems.org/gems/memcache]
         | 
| 28 | 
            +
            * Dalli[https://rubygems.org/gems/dalli]
         | 
| 27 29 |  | 
| 28 30 | 
             
            options:
         | 
| 29 31 |  | 
| 30 32 | 
             
              {
         | 
| 31 33 | 
             
                :ttl => 3600, # time to live. default 3600
         | 
| 32 | 
            -
                :ignore_exception => false, # through exception. default false
         | 
| 33 34 | 
             
                :pack_lib => MessagePack, # cache packing library. This Object should be have pack / unpack method.
         | 
| 34 | 
            -
                :query_cache => false # enable query cache. default  | 
| 35 | 
            +
                :query_cache => false # enable query cache. default false
         | 
| 35 36 | 
             
              }
         | 
| 36 37 |  | 
| 37 38 | 
             
            == Cache Timing
         | 
| @@ -48,7 +49,7 @@ options: | |
| 48 49 | 
             
              * clear all query caches of model
         | 
| 49 50 |  | 
| 50 51 | 
             
            == Contributing to sequel-cacheable
         | 
| 51 | 
            -
             | 
| 52 | 
            +
             | 
| 52 53 | 
             
            * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
         | 
| 53 54 | 
             
            * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
         | 
| 54 55 | 
             
            * Fork the project.
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -1,37 +1,2 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require 'rubygems'
         | 
| 4 | 
            -
            require 'bundler'
         | 
| 5 | 
            -
            begin
         | 
| 6 | 
            -
              Bundler.setup(:default, :development)
         | 
| 7 | 
            -
            rescue Bundler::BundlerError => e
         | 
| 8 | 
            -
              $stderr.puts e.message
         | 
| 9 | 
            -
              $stderr.puts "Run `bundle install` to install missing gems"
         | 
| 10 | 
            -
              exit e.status_code
         | 
| 11 | 
            -
            end
         | 
| 12 | 
            -
            require 'rake'
         | 
| 13 | 
            -
             | 
| 14 | 
            -
            require 'jeweler'
         | 
| 15 | 
            -
            Jeweler::Tasks.new do |gem|
         | 
| 16 | 
            -
              # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
         | 
| 17 | 
            -
              gem.name = "sequel-cacheable"
         | 
| 18 | 
            -
              gem.homepage = "http://github.com/rosylilly/sequel-cacheable"
         | 
| 19 | 
            -
              gem.license = "MIT"
         | 
| 20 | 
            -
              gem.summary = %Q{This plug-in caching mechanism to implement the Model of the Sequel}
         | 
| 21 | 
            -
              gem.description = %Q{This plug-in caching mechanism to implement the Model of the Sequel}
         | 
| 22 | 
            -
              gem.email = "rosylilly@aduca.org"
         | 
| 23 | 
            -
              gem.authors = ["Sho Kusano <rosylilly>"]
         | 
| 24 | 
            -
              # dependencies defined in Gemfile
         | 
| 25 | 
            -
            end
         | 
| 26 | 
            -
            Jeweler::RubygemsDotOrgTasks.new
         | 
| 27 | 
            -
             | 
| 28 | 
            -
            require 'rspec/core'
         | 
| 29 | 
            -
            require 'rspec/core/rake_task'
         | 
| 30 | 
            -
            RSpec::Core::RakeTask.new(:spec) do |spec|
         | 
| 31 | 
            -
              spec.pattern = FileList['spec/**/*_spec.rb']
         | 
| 32 | 
            -
            end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
            task :default => :spec
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            require 'yard'
         | 
| 37 | 
            -
            YARD::Rake::YardocTask.new
         | 
| 2 | 
            +
            require "bundler/gem_tasks"
         | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Sequel::Plugins
         | 
| 4 | 
            +
              module Cacheable
         | 
| 5 | 
            +
                module ClassMethods
         | 
| 6 | 
            +
                  attr_reader :cache_driver, :cache_options, :caches
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def inherited(subclass)
         | 
| 9 | 
            +
                    super
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def primary_key_lookup(id)
         | 
| 13 | 
            +
                    cache_fetch(id.to_s) do
         | 
| 14 | 
            +
                      super
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def restore_by_cache(hash)
         | 
| 19 | 
            +
                    return nil if hash.nil?
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    return hash.map{|hs| restore_by_cache(hs) } if hash.is_a?(Array)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    return hash if hash.kind_of?(Sequel::Model)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    hash.keys.each do | key |
         | 
| 26 | 
            +
                      value = hash.delete(key)
         | 
| 27 | 
            +
                      key = key.to_sym rescue key
         | 
| 28 | 
            +
                      case db_schema[key][:type]
         | 
| 29 | 
            +
                      when :date
         | 
| 30 | 
            +
                        value = Date.new(*value)
         | 
| 31 | 
            +
                      when :time
         | 
| 32 | 
            +
                        value = Sequel::SQLTime.at(value[0], value[1])
         | 
| 33 | 
            +
                      when :datetime
         | 
| 34 | 
            +
                        value = Time.at(value[0], value[1])
         | 
| 35 | 
            +
                      when :decimal
         | 
| 36 | 
            +
                        value = BigDecimal.new(value)
         | 
| 37 | 
            +
                      when :integer
         | 
| 38 | 
            +
                        value = value.to_i
         | 
| 39 | 
            +
                      end
         | 
| 40 | 
            +
                      hash[key] = value
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    return new(hash, true)
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def cache_key(key)
         | 
| 47 | 
            +
                    "#{self.name}:#{key}"
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def cache_set(key, value, ttl = @cache_options[:ttl])
         | 
| 51 | 
            +
                    @caches[key.match(/\AQuery:/) ? :query : :instance] << key
         | 
| 52 | 
            +
                    cache_driver.set(cache_key(key), value, ttl)
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def cache_get(key)
         | 
| 56 | 
            +
                    restore_by_cache(cache_driver.get(cache_key(key)))
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  def cache_fetch(key, ttl = @cache_options[:ttl], &block)
         | 
| 60 | 
            +
                    @caches[key.match(/\AQuery:/) ? :query : :instance] << key
         | 
| 61 | 
            +
                    cache_driver.fetch(cache_key(key), ttl, &block)
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  def cache_del(key)
         | 
| 65 | 
            +
                    @caches[key.match(/\AQuery:/) ? :query : :instance].delete(key)
         | 
| 66 | 
            +
                    cache_driver.del(cache_key(key))
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  def cache_clear(type)
         | 
| 70 | 
            +
                    @caches[type].dup.each {|key| cache_del(key) }
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
| @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Sequel::Plugins
         | 
| 4 | 
            +
              module Cacheable
         | 
| 5 | 
            +
                module DatasetMethods
         | 
| 6 | 
            +
                  def all(*args, &block)
         | 
| 7 | 
            +
                    if(
         | 
| 8 | 
            +
                      model &&
         | 
| 9 | 
            +
                      model.respond_to?(:cache_fetch) &&
         | 
| 10 | 
            +
                      model.cache_options[:query_cache] &&
         | 
| 11 | 
            +
                      @row_proc.kind_of?(Class) &&
         | 
| 12 | 
            +
                      @row_proc.included_modules.include?(Sequel::Model::InstanceMethods)
         | 
| 13 | 
            +
                    )
         | 
| 14 | 
            +
                      @row_proc.cache_fetch(cache_key) do
         | 
| 15 | 
            +
                        super(*args, &block)
         | 
| 16 | 
            +
                      end
         | 
| 17 | 
            +
                    else
         | 
| 18 | 
            +
                      super(*args, &block)
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def first(*args)
         | 
| 23 | 
            +
                    if(
         | 
| 24 | 
            +
                      model &&
         | 
| 25 | 
            +
                      model.respond_to?(:cache_fetch) &&
         | 
| 26 | 
            +
                      model.cache_options[:query_cache] &&
         | 
| 27 | 
            +
                      @row_proc.kind_of?(Class) &&
         | 
| 28 | 
            +
                      @row_proc.included_modules.include?(Sequel::Model::InstanceMethods)
         | 
| 29 | 
            +
                    )
         | 
| 30 | 
            +
                      @row_proc.cache_fetch("#{cache_key}:first") do
         | 
| 31 | 
            +
                        super(*args)
         | 
| 32 | 
            +
                      end
         | 
| 33 | 
            +
                    else
         | 
| 34 | 
            +
                      super(*args)
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  def with_pk(pk)
         | 
| 39 | 
            +
                    if pk.is_a(Integer)
         | 
| 40 | 
            +
                      model.cache_fetch(pk.to_s) do
         | 
| 41 | 
            +
                        super(pk)
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
                    else
         | 
| 44 | 
            +
                      super(pk)
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def cache_key
         | 
| 49 | 
            +
                    "Query:#{select_sql.gsub(/ +/, '_')}"
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            module Sequel::Plugins
         | 
| 2 | 
            +
              module Cacheable
         | 
| 3 | 
            +
                class DalliDriver < Driver
         | 
| 4 | 
            +
                  def del(key)
         | 
| 5 | 
            +
                    @store.delete(key)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                    return nil
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def expire(key, time)
         | 
| 11 | 
            +
                    if time > 0
         | 
| 12 | 
            +
                      @store.touch(key, time)
         | 
| 13 | 
            +
                    else
         | 
| 14 | 
            +
                      @store.delete(key)
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            module Sequel::Plugins
         | 
| 2 | 
            +
              module Cacheable
         | 
| 3 | 
            +
                DRIVERS = %w(memcache dalli redis).freeze
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                class Driver
         | 
| 6 | 
            +
                  def self.factory(*args)
         | 
| 7 | 
            +
                    case args[0].class.name
         | 
| 8 | 
            +
                    when 'Memcache'
         | 
| 9 | 
            +
                      MemcacheDriver.new(*args)
         | 
| 10 | 
            +
                    when 'Dalli::Client'
         | 
| 11 | 
            +
                      DalliDriver.new(*args)
         | 
| 12 | 
            +
                    when 'Redis'
         | 
| 13 | 
            +
                      RedisDriver.new(*args)
         | 
| 14 | 
            +
                    else
         | 
| 15 | 
            +
                      Driver.new(*args)
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def initialize(store, pack_lib = MessagePackPacker)
         | 
| 20 | 
            +
                    @store = store
         | 
| 21 | 
            +
                    @packer = pack_lib
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def get(key)
         | 
| 25 | 
            +
                    val = @store.get(key)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    return val.nil? || val.empty? ? nil : @packer.unpack(val)
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def set(key, val, expire = nil)
         | 
| 31 | 
            +
                    @store.set(key, @packer.pack(val))
         | 
| 32 | 
            +
                    expire(key, expire) unless expire.nil?
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    return val
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  def del(key)
         | 
| 38 | 
            +
                    @store.del(key)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    return nil
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def expire(key, time)
         | 
| 44 | 
            +
                    @store.expire(key, time)
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  def fetch(key, *args, &block)
         | 
| 48 | 
            +
                    get(key) || set(key, block.call(*args))
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            Sequel::Plugins::Cacheable::DRIVERS.each do |driver|
         | 
| 55 | 
            +
              require "sequel-cacheable/driver/#{driver}"
         | 
| 56 | 
            +
            end
         | 
| @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Sequel::Plugins
         | 
| 4 | 
            +
              module Cacheable
         | 
| 5 | 
            +
                module InstanceMethods
         | 
| 6 | 
            +
                  def after_initialize
         | 
| 7 | 
            +
                    super
         | 
| 8 | 
            +
                    cache! unless id.nil?
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def after_save
         | 
| 12 | 
            +
                    super
         | 
| 13 | 
            +
                    recache!
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def delete(*args)
         | 
| 17 | 
            +
                    uncache!
         | 
| 18 | 
            +
                    super
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  def destory(*args)
         | 
| 22 | 
            +
                    uncache!
         | 
| 23 | 
            +
                    super(*args)
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  def cache!
         | 
| 27 | 
            +
                    model.cache_set(cache_key, self)
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def uncache!
         | 
| 31 | 
            +
                    model.cache_del(cache_key)
         | 
| 32 | 
            +
                    model.cache_clear(:query)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def recache!
         | 
| 36 | 
            +
                    uncache!
         | 
| 37 | 
            +
                    cache!
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def cache_key
         | 
| 41 | 
            +
                    "#{self.id.to_s}"
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  def to_msgpack(*args)
         | 
| 45 | 
            +
                    msgpack_hash.to_msgpack
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def msgpack_hash
         | 
| 49 | 
            +
                    hash = {}
         | 
| 50 | 
            +
                    @values.each_pair do | key, value |
         | 
| 51 | 
            +
                      case value
         | 
| 52 | 
            +
                      when Date
         | 
| 53 | 
            +
                        value = [value.year, value.mon, value.mday, value.start]
         | 
| 54 | 
            +
                      when Sequel::SQLTime, Time
         | 
| 55 | 
            +
                        value = [value.to_i, value.usec]
         | 
| 56 | 
            +
                      when BigDecimal, Bignum
         | 
| 57 | 
            +
                        value = value.to_s
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
                      hash[key] = value
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                    hash
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                  private :msgpack_hash
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            require 'msgpack'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Sequel::Plugins
         | 
| 4 | 
            +
              module Cacheable
         | 
| 5 | 
            +
                class Packer
         | 
| 6 | 
            +
                  def self.factory(lib)
         | 
| 7 | 
            +
                    case lib
         | 
| 8 | 
            +
                    when MessagePack
         | 
| 9 | 
            +
                      MessagePackPacker.new
         | 
| 10 | 
            +
                    else
         | 
| 11 | 
            +
                      Packer.new
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  def pack(obj)
         | 
| 16 | 
            +
                    Marshal.dump(obj)
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def unpack(string)
         | 
| 20 | 
            +
                    Marshal.load(string)
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                class MessagePackPacker < Packer
         | 
| 25 | 
            +
                  def pack(obj)
         | 
| 26 | 
            +
                    obj.to_msgpack
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  def unpack(string)
         | 
| 30 | 
            +
                    MessagePack.unpack(string)
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         |