rediska 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+ dump.rdb
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --format progress
3
+ --drb
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'rdoc'
5
+
6
+ # Specify your gem's dependencies in rediska.gemspec
7
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rediska (0.0.2)
5
+ redis (~> 3.0.0)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ coderay (1.0.9)
11
+ columnize (0.3.6)
12
+ coveralls (0.7.0)
13
+ multi_json (~> 1.3)
14
+ rest-client
15
+ simplecov (>= 0.7)
16
+ term-ansicolor
17
+ thor
18
+ debugger (1.6.2)
19
+ columnize (>= 0.3.1)
20
+ debugger-linecache (~> 1.2.0)
21
+ debugger-ruby_core_source (~> 1.2.3)
22
+ debugger-linecache (1.2.0)
23
+ debugger-ruby_core_source (1.2.3)
24
+ diff-lcs (1.2.4)
25
+ json (1.8.1)
26
+ method_source (0.8.2)
27
+ mime-types (1.25)
28
+ multi_json (1.8.2)
29
+ pry (0.9.12.2)
30
+ coderay (~> 1.0.5)
31
+ method_source (~> 0.8)
32
+ slop (~> 3.4)
33
+ pry-debugger (0.2.2)
34
+ debugger (~> 1.3)
35
+ pry (~> 0.9.10)
36
+ rake (10.1.0)
37
+ rdoc (4.0.1)
38
+ json (~> 1.4)
39
+ redis (3.0.5)
40
+ rest-client (1.6.7)
41
+ mime-types (>= 1.16)
42
+ rspec (2.14.1)
43
+ rspec-core (~> 2.14.0)
44
+ rspec-expectations (~> 2.14.0)
45
+ rspec-mocks (~> 2.14.0)
46
+ rspec-core (2.14.6)
47
+ rspec-expectations (2.14.3)
48
+ diff-lcs (>= 1.1.3, < 2.0)
49
+ rspec-mocks (2.14.4)
50
+ simplecov (0.7.1)
51
+ multi_json (~> 1.0)
52
+ simplecov-html (~> 0.7.1)
53
+ simplecov-html (0.7.1)
54
+ slop (3.4.6)
55
+ term-ansicolor (1.2.2)
56
+ tins (~> 0.8)
57
+ thor (0.18.1)
58
+ tins (0.11.0)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ coveralls
65
+ pry
66
+ pry-debugger
67
+ rake
68
+ rdoc
69
+ rediska!
70
+ rspec (~> 2.14)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Leonid Beder
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # Rediska
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rediska.png)](http://badge.fury.io/rb/rediska)
4
+ [![Build Status](https://travis-ci.org/lbeder/rediska.png)](https://travis-ci.org/lbeder/rediska)
5
+ [![Dependency Status](https://gemnasium.com/andrew/split.png)](https://gemnasium.com/lbeder/rediska)
6
+ [![Coverage Status](https://coveralls.io/repos/lbeder/rediska/badge.png)](https://coveralls.io/r/lbeder/rediska)
7
+
8
+ This is a light-weight implementation of a redis simulator, which is useful for local development and testing or for minimal environments (where a real redis server might not be available or even desired, while every worker matters).
9
+
10
+ Currently, rediska is currently only compliant with redis 3 and supports the following database strategies:
11
+
12
+ * Memory (default): the data is being stored entirely in the memory and is not persistent nor shared between different processed.
13
+ * Filesystem: the data is being backed by the filesystem and even though slower than the in-memory implementation, it does provides persistency (to some extent, as the data is being stored in a temporary folder) and can be accessed across the different processes.
14
+
15
+ ## Setup
16
+
17
+ If you are using bundler add rediska to your Gemfile:
18
+
19
+ ``` ruby
20
+ gem 'rediska'
21
+ ```
22
+
23
+ Then run:
24
+
25
+ ```bash
26
+ $ bundle install
27
+ ```
28
+
29
+ Otherwise install the gem:
30
+
31
+ ```bash
32
+ $ gem install rediska
33
+ ```
34
+
35
+ ## Usage
36
+ The gem will automatically add its fake driver to Redis::Connection.drivers, so not extra configuration is required, other than conditionally bundling the gem (for example, in Rails' "test", "development", "continuos_integration" groups, per-your requirements.
37
+
38
+ ## Configuration
39
+
40
+ ### Database type/strategy
41
+ Rediska supports the following database strategies:
42
+
43
+ * Memory (:memory): the data is being stored entirely in the memory and is not persistent nor shared between different processed.
44
+ * Filesystem (:filesystem): the data is being backed by the filesystem and even though slower than the in-memory implementation, it does provides persistency (to some extent, as the data is being stored in a temporary folder) and can be accessed across the different processes.
45
+
46
+ By default, rediska uses the in-memory strategy.
47
+
48
+ To override this behavior you can config the ```database``` option like so:
49
+
50
+ ```ruby
51
+ Rediska.configure do |config|
52
+ config.database = :filesystem
53
+ end
54
+ ```
55
+
56
+ ### Adding namespace
57
+
58
+ If you choose to use the filesystem backed database, you can append an additional namespace in order to prevent conflicts like so:
59
+
60
+ ```ruby
61
+ Rediska.configure do |config|
62
+ config.namespace = 'test'
63
+ end
64
+ ```
65
+
66
+ ## Credits and Contributors
67
+
68
+ This gem was inspired (and originally forked from) by the [fakeredis](https://github.com/guilleiguaran/fakeredis) gem.
69
+
70
+ ## License
71
+
72
+ The MIT License (MIT)
73
+
74
+ Copyright (c) 2013
75
+
76
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
77
+ this software and associated documentation files (the "Software"), to deal in
78
+ the Software without restriction, including without limitation the rights to
79
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
80
+ the Software, and to permit persons to whom the Software is furnished to do so,
81
+ subject to the following conditions:
82
+
83
+ The above copyright notice and this permission notice shall be included in all
84
+ copies or substantial portions of the Software.
85
+
86
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
87
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
88
+ FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
89
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
90
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
91
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
92
+
93
+ <div align="center">
94
+ <img alt='rediska' src="http://farm6.staticflickr.com/5189/5640624758_b6717935bf.jpg" />
95
+ </div>
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ task :default => :spec
@@ -0,0 +1,11 @@
1
+ module Rediska
2
+ Redis = ::Redis
3
+
4
+ class Configuration
5
+ attr_accessor :database, :namespace
6
+
7
+ def initialize
8
+ @database = :memory
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,67 @@
1
+ require 'rediska/databases/memory'
2
+ require 'rediska/databases/pstore'
3
+ require 'rediska/sorted_set_argument_handler'
4
+ require 'rediska/sorted_set_store'
5
+ require 'rediska/zset'
6
+ require 'rediska/driver'
7
+
8
+ module Rediska
9
+ class Connection
10
+ include Driver
11
+
12
+ class << self
13
+ def databases
14
+ @databases ||= Hash.new {|h,k| h[k] = [] }
15
+ end
16
+
17
+ def reset
18
+ if @databases
19
+ @databases.values do |db|
20
+ db.class.reset
21
+ db.each(&:clear)
22
+ end
23
+
24
+ @databases = nil
25
+ end
26
+ end
27
+
28
+ def connect(options = {})
29
+ new(options)
30
+ end
31
+ end
32
+
33
+ def initialize(options = {})
34
+ @options = options
35
+ @database_id = 0
36
+ end
37
+
38
+ def database_instance_key
39
+ @database_instance_key ||= [@options[:host], @options[:port], Rediska.configuration.namespace].
40
+ compact.join(':')
41
+ end
42
+
43
+ def databases
44
+ self.class.databases[database_instance_key]
45
+ end
46
+
47
+ def find_database(id = database_id)
48
+ databases[id] ||= db_class.new(database_instance_key, id)
49
+ end
50
+
51
+ def data
52
+ find_database
53
+ end
54
+
55
+ private
56
+ def db_class
57
+ case Rediska.configuration.database
58
+ when :memory
59
+ Rediska::Databases::Memory
60
+ when :filesystem
61
+ Rediska::Databases::PStore
62
+ else
63
+ raise ArgumentError, "invalid database type: #{Rediska.configuration.database}"
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,87 @@
1
+ module Rediska
2
+ module Databases
3
+ module Expiring
4
+ def self.included(base)
5
+ base.send(:include, InstanceMethods)
6
+ base.extend ClassMethods
7
+
8
+ attr_reader :expires
9
+ end
10
+
11
+ module InstanceMethods
12
+ def initialize
13
+ super
14
+
15
+ @expires = {}
16
+ end
17
+
18
+ def [](key)
19
+ key = normalize(key)
20
+ delete(key) if expired?(key)
21
+
22
+ super
23
+ end
24
+
25
+ def []=(key, val)
26
+ key = normalize(key)
27
+ expire(key)
28
+
29
+ super
30
+ end
31
+
32
+ def delete(key)
33
+ key = normalize(key)
34
+ expire(key)
35
+
36
+ super
37
+ end
38
+
39
+ def expire(key)
40
+ key = normalize(key)
41
+ expires.delete(key)
42
+ end
43
+
44
+ def expired?(key)
45
+ key = normalize(key)
46
+ expires.include?(key) && expires[key] < Time.now
47
+ end
48
+
49
+ def key?(key)
50
+ key = normalize(key)
51
+ delete(key) if expired?(key)
52
+
53
+ super
54
+ end
55
+
56
+ def values_at(*keys)
57
+ keys.each do |key|
58
+ key = normalize(key)
59
+ delete(key) if expired?(key)
60
+ end
61
+
62
+ super
63
+ end
64
+
65
+ def keys
66
+ super.select do |key|
67
+ key = normalize(key)
68
+
69
+ if expired?(key)
70
+ delete(key)
71
+ false
72
+ else
73
+ true
74
+ end
75
+ end
76
+ end
77
+
78
+ def normalize(key)
79
+ key.to_s
80
+ end
81
+ end
82
+
83
+ module ClassMethods
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,21 @@
1
+ require 'rediska/databases/expiring'
2
+
3
+ module Rediska
4
+ module Databases
5
+ class Memory < Hash
6
+ include Expiring
7
+
8
+ def initialize(instance_key, id)
9
+ super()
10
+ end
11
+
12
+ class << self
13
+ def flushdb(instance_key, id)
14
+ end
15
+
16
+ def flushall(instance_key)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,72 @@
1
+ require 'pstore'
2
+ require 'tmpdir'
3
+
4
+ require 'rediska/databases/expiring'
5
+
6
+ module Rediska
7
+ module Utilities
8
+ class SyncedPStore < ::PStore
9
+ def initialize(file)
10
+ super(file, false)
11
+ end
12
+
13
+ def transaction(read_only = false, &block)
14
+ @flock ||= path + '.lock'
15
+
16
+ File.open(@flock, File::RDWR | File::CREAT) do
17
+ super
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ module Databases
24
+ class PStore
25
+ include Expiring
26
+
27
+ def initialize(instance_key, id)
28
+ @id = id
29
+
30
+ @store = self.class.pstore(instance_key)
31
+ @store.transaction do
32
+ @store[db_name] ||= {}
33
+ @db = @store[db_name]
34
+ end
35
+
36
+ super()
37
+ end
38
+
39
+ def method_missing(*args, &block)
40
+ @store.transaction do
41
+ hash = @db
42
+ hash.send(*args, &block)
43
+ end
44
+ end
45
+
46
+ class << self
47
+ def flushdb(instance_key, id)
48
+ store = pstore(instance_key)
49
+ store.transaction { store.delete(db_name(id)) }
50
+ end
51
+
52
+ def flushall(instance_key)
53
+ store = pstore(instance_key)
54
+ store.transaction { store.roots.each {|r| store.delete(r) } }
55
+ end
56
+
57
+ def pstore(instance_key)
58
+ Utilities::SyncedPStore.new(File.join(Dir.tmpdir, instance_key.to_s))
59
+ end
60
+
61
+ def db_name(id)
62
+ "redis-#{id}"
63
+ end
64
+ end
65
+
66
+ private
67
+ def db_name
68
+ self.class.db_name(@id)
69
+ end
70
+ end
71
+ end
72
+ end