redis_rds 0.1.1
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.
- checksums.yaml +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +18 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +91 -0
- data/Rakefile +99 -0
- data/bin/console +10 -0
- data/bin/setup +8 -0
- data/doc/ROADMAP.md +10 -0
- data/lib/redis_rds/composite.rb +46 -0
- data/lib/redis_rds/config.rb +36 -0
- data/lib/redis_rds/expirable_hash.rb +61 -0
- data/lib/redis_rds/hash.rb +76 -0
- data/lib/redis_rds/list.rb +50 -0
- data/lib/redis_rds/mutex.rb +56 -0
- data/lib/redis_rds/nested_hash.rb +38 -0
- data/lib/redis_rds/object.rb +74 -0
- data/lib/redis_rds/set.rb +60 -0
- data/lib/redis_rds/sorted_set.rb +61 -0
- data/lib/redis_rds/sorted_string_set.rb +30 -0
- data/lib/redis_rds/string.rb +43 -0
- data/lib/redis_rds/version.rb +3 -0
- data/lib/redis_rds.rb +20 -0
- data/redis_rds.gemspec +29 -0
- data/redis_rds.sublime-project +23 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fe5fdbd19701e3212b3dd6f36b9ccb7717ab60d9
|
4
|
+
data.tar.gz: fbe1a8aa69abecd838a8659a3175114135c67afb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6fab513e4524e3ef4375540a52fac2f7efac0a77b2bd7fc7c9a0a12e0cfacc0a8fcb2adbd0921ccb27a67d07a69de9d07261ec566551bc29218597544be3a8f1
|
7
|
+
data.tar.gz: 72cae17306552b4f7807f4163caee1950d73eac99d99be99ff61abbf096d3178eed31ac0479120ab3ca69b5802ef1435b952119749e2c9f93a3088709db483a2
|
data/.coveralls.yml
ADDED
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
##0.1.1
|
4
|
+
|
5
|
+
- [6617250](https://github.com/barcoo/redis_rds/commit/6617250) *2016-07-24* __move tests to test/redis_rds__ (Sergio Medina)
|
6
|
+
- [48d8c0b](https://github.com/barcoo/redis_rds/commit/48d8c0b) *2016-07-24* __run tests in random order__ (Sergio Medina)
|
7
|
+
- [2fe8944](https://github.com/barcoo/redis_rds/commit/2fe8944) *2016-07-24* __require only active record core extensions__ (Sergio Medina)
|
8
|
+
- [9cf87a8](https://github.com/barcoo/redis_rds/commit/9cf87a8) *2016-07-24* __ignore vim temp and swap files__ (Sergio Medina)
|
9
|
+
- [96b541b](https://github.com/barcoo/redis_rds/commit/96b541b) *2016-07-23* __drop rails dependency and use default bundler gem scaffolding__ (Sergio Medina)
|
10
|
+
- [2cce40e](https://github.com/barcoo/redis_rds/commit/2cce40e) *2016-07-19* __fix broken link__ (Sergio Medina)
|
11
|
+
- [9afe525](https://github.com/barcoo/redis_rds/commit/9afe525) *2016-07-19* __build status added, removing it from the roadmap__ (Sergio Medina)
|
12
|
+
- [aecb26b](https://github.com/barcoo/redis_rds/commit/aecb26b) *2016-07-19* __use travis badge for master branch__ (Sergio Medina)
|
13
|
+
- [db3ffb2](https://github.com/barcoo/redis_rds/commit/db3ffb2) *2016-07-19* __add travis CI config__ (Sergio Medina)
|
14
|
+
- [0dc4578](https://github.com/barcoo/redis_rds/commit/0dc4578) *2016-07-19* __move RedisSingleton.clear_test_db to setup in test_helper__ (Sergio Medina)
|
15
|
+
|
16
|
+
##0.1.0
|
17
|
+
|
18
|
+
- [b97c0c4](https://github.com/barcoo/redis_rds/commit/b97c0c4) *2016-07-18* __bump version to 0.1.0__ (Sergio Medina)
|
19
|
+
- [4a29c74](https://github.com/barcoo/redis_rds/commit/4a29c74) *2016-07-18* __remove configuration through YAML files__ (Sergio Medina)
|
20
|
+
- [c8534b3](https://github.com/barcoo/redis_rds/commit/c8534b3) *2016-07-18* __small changes to Roadmap__ (Sergio Medina)
|
21
|
+
|
22
|
+
##0.0.4
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
##0.0.3
|
27
|
+
|
28
|
+
- [6dd41ea](https://github.com/barcoo/redis_rds/commit/6dd41ea) *2016-07-17* __version bump__ (Sergio Medina)
|
29
|
+
- [0431cd1](https://github.com/barcoo/redis_rds/commit/0431cd1) *2016-07-17* __ignore README.md-u__ (Sergio Medina)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Checkitmobile GmbH
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all 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,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# RedisRds
|
2
|
+
|
3
|
+
[](https://github.com/barcoo/redis_rds/releases/tag/0.1.1)
|
4
|
+
[](https://travis-ci.org/barcoo/redis_rds)
|
5
|
+
[](https://coveralls.io/github/barcoo/redis_rds?branch=master)
|
6
|
+
|
7
|
+
Ruby data structures stored in Redis.
|
8
|
+
|
9
|
+
RedisRds provides Redis-backed Ruby interfaces for the following data structures:
|
10
|
+
|
11
|
+
* String
|
12
|
+
* Hash
|
13
|
+
* ExpirableHash
|
14
|
+
* NestedHash
|
15
|
+
* List
|
16
|
+
* Mutex
|
17
|
+
* Set
|
18
|
+
* SortedSet
|
19
|
+
* SortedStringSet
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
Add to your gemfile:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem 'redis_rds', git: 'git@github.com:barcoo/redis_rds.git'
|
27
|
+
```
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
Best is to check [the tests](test/) to see how to use the data structures.
|
32
|
+
Here are two examples, for Mutex and String:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
# configure RedisRds by passing either a connection
|
36
|
+
RedisRds.configure(connection: my_redis_connection, namespace: 'my_app')
|
37
|
+
# or connection parameters
|
38
|
+
RedisRds.configure(
|
39
|
+
host: 'localhost',
|
40
|
+
db: 1,
|
41
|
+
port: 6379,
|
42
|
+
namespace: 'my_app',
|
43
|
+
)
|
44
|
+
```
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
my_semaphore = RedisRds::Mutex.new('a_key')
|
48
|
+
my_semaphore.synchronize do
|
49
|
+
# do something with a shared resource
|
50
|
+
write_file()
|
51
|
+
end # mutex released, another thread can use the resource
|
52
|
+
```
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
string_a = RedisRds::String.new('some_key')
|
56
|
+
string_a = 'hello'
|
57
|
+
|
58
|
+
string_b = RedisRds::String.new('some_key')
|
59
|
+
puts string_b
|
60
|
+
# 'hello'
|
61
|
+
```
|
62
|
+
|
63
|
+
## Contributing
|
64
|
+
|
65
|
+
Take a look at the [Roadmap](doc/ROADMAP.md) and lint your code using [rubocop](https://github.com/bbatsov/rubocop) and our [rubocop.yml](.rubocop.yml) file.
|
66
|
+
|
67
|
+
To run the tests, start a Redis server on localhost and run `bundle exec rake test`.
|
68
|
+
|
69
|
+
To contribute:
|
70
|
+
|
71
|
+
1. Fork it
|
72
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
74
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
75
|
+
5. Create new Pull Request
|
76
|
+
|
77
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
78
|
+
|
79
|
+
## Release
|
80
|
+
|
81
|
+
___Note___: eventually use one of the popular git release scripts to tag, create tag notes, etc., based on git changelog.
|
82
|
+
|
83
|
+
When you want to create a new release, use the rake task ```cim:release``` (in the main Rakefile)
|
84
|
+
|
85
|
+
```shell
|
86
|
+
bundle exec rake cim:release
|
87
|
+
```
|
88
|
+
|
89
|
+
## License
|
90
|
+
|
91
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << 'test'
|
6
|
+
t.libs << 'lib'
|
7
|
+
t.test_files = FileList['test/**/*_test.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
task default: :test
|
11
|
+
|
12
|
+
namespace :cim do
|
13
|
+
desc 'Tags, updates README, and CHANGELOG and pushes to Github. Requires ruby-git'
|
14
|
+
task :release do
|
15
|
+
tasks = ['cim:assert_clean_repo', 'cim:git_fetch', 'cim:assert_version', 'cim:update_readme', 'cim:update_changelog', 'cim:commit_changes', 'cim:tag']
|
16
|
+
begin
|
17
|
+
tasks.each { |task| Rake::Task[task].invoke }
|
18
|
+
`git push && git push origin '#{RedisRds::VERSION}'`
|
19
|
+
rescue => error
|
20
|
+
puts ">>> ERROR: #{error}; might want to reset your repository"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Fails if the current repository is not clean'
|
25
|
+
task :assert_clean_repo do
|
26
|
+
status = `git status -s`.chomp.strip
|
27
|
+
if status.empty?
|
28
|
+
status = `git log origin/master..HEAD`.chomp.strip # check if we have unpushed commits
|
29
|
+
if status.empty?
|
30
|
+
puts '>>> Repository is clean!'
|
31
|
+
else
|
32
|
+
puts '>>> Please push your committed changes before releasing!'
|
33
|
+
exit -1
|
34
|
+
end
|
35
|
+
else
|
36
|
+
puts '>>> Please stash or commit your changes before releasing!'
|
37
|
+
exit -1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'Fetches latest tags/commits'
|
42
|
+
task :git_fetch do
|
43
|
+
puts '>>> Fetching latest git refs'
|
44
|
+
`git fetch --tags`
|
45
|
+
end
|
46
|
+
|
47
|
+
desc 'Fails if the current gem version is not greater than the last tag'
|
48
|
+
task :assert_version do
|
49
|
+
latest = `git describe --abbrev=0`.chomp.strip
|
50
|
+
current = RedisRds::VERSION
|
51
|
+
|
52
|
+
unless Gem::Version.new(current) > Gem::Version.new(latest)
|
53
|
+
puts ">>> Latest tagged version is #{latest}; make sure gem version (#{current}) is greater!"
|
54
|
+
exit -1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'Updates README with latest version'
|
59
|
+
task :update_readme do
|
60
|
+
puts '>>> Updating README.md'
|
61
|
+
replace = %([](https://github.com/barcoo/redis_rds/releases/tag/#{RedisRds::VERSION}))
|
62
|
+
|
63
|
+
`sed -i -u 's@^\\[\\!\\[GitHub release\\].*$@#{replace}@' README.md`
|
64
|
+
end
|
65
|
+
|
66
|
+
desc 'Updates CHANGELOG with commit log from last tag to this one'
|
67
|
+
task :update_changelog do
|
68
|
+
puts '>>> Updating CHANGELOG.md'
|
69
|
+
latest = `git describe --abbrev=0`.chomp.strip
|
70
|
+
log = `git log --pretty=format:'- [%h](https://github.com/barcoo/redis_rds/commit/%h) *%ad* __%s__ (%an)' --date=short '#{latest}'..HEAD`.chomp
|
71
|
+
|
72
|
+
changelog = File.open('.CHANGELOG.md', 'w')
|
73
|
+
changelog.write("# Changelog\n\n###{RedisRds::VERSION}\n\n#{log}\n\n")
|
74
|
+
File.open('CHANGELOG.md', 'r') do |file|
|
75
|
+
file.readline # skip first two lines
|
76
|
+
file.readline
|
77
|
+
while buffer = file.read(2048)
|
78
|
+
changelog.write(buffer)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
changelog.close
|
83
|
+
`mv '.CHANGELOG.md' 'CHANGELOG.md'`
|
84
|
+
end
|
85
|
+
|
86
|
+
desc 'Commits the README/CHANGELOG changes'
|
87
|
+
task :commit_changes do
|
88
|
+
puts '>>> Committing updates to README/CHANGELOG'
|
89
|
+
`git commit -am'Updated README.md and CHANGELOG.md on new release'`
|
90
|
+
end
|
91
|
+
|
92
|
+
desc 'Creates and pushes the tag to git'
|
93
|
+
task :tag do
|
94
|
+
puts '>>> Tagging'
|
95
|
+
message = STDOUT.print '>>> Please enter a tag message: '
|
96
|
+
input = STDIN.gets.strip.tr("'", "\'")
|
97
|
+
`git tag -a '#{RedisRds::VERSION}' -m '#{input}'`
|
98
|
+
end
|
99
|
+
end
|
data/bin/console
ADDED
data/bin/setup
ADDED
data/doc/ROADMAP.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Roadmap
|
2
|
+
|
3
|
+
- Add to RubyGems
|
4
|
+
- Remove ActiveSupport dependency
|
5
|
+
- Add documentation (use yard)
|
6
|
+
- Add support for Redis authentication (or simply remove config by params and only accept a connection?)
|
7
|
+
- Implement lazy enumerators (see Hash for instance)
|
8
|
+
- Improve lib configuration (use Configuration class, allow multiple instances)
|
9
|
+
- Use hashes for optional parameters (f.i. see Mutex::initialize)
|
10
|
+
- Add support for latest Redis commands (f.i. Geospatial commands)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class Composite
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
attr_reader :members
|
6
|
+
def_delegators :@members, :[], :[]=, :assoc, :size, :empty?, :each, :include?, :length, :merge
|
7
|
+
|
8
|
+
def initialize(key)
|
9
|
+
@key = key
|
10
|
+
@members = {}.with_indifferent_access
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(key, klass)
|
14
|
+
object = klass.new(format_member_key(key))
|
15
|
+
@members[key] = object
|
16
|
+
end
|
17
|
+
|
18
|
+
def format_member_key(key)
|
19
|
+
return "#{@key}:#{key}"
|
20
|
+
end
|
21
|
+
private :format_member_key
|
22
|
+
|
23
|
+
def delete(key)
|
24
|
+
if @members.key?(key)
|
25
|
+
@members[key].delete
|
26
|
+
@members.delete(key)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def clear
|
31
|
+
@members.each do |k, _|
|
32
|
+
self.delete(k)
|
33
|
+
end
|
34
|
+
@members.clear
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_missing(*args)
|
38
|
+
result = nil
|
39
|
+
|
40
|
+
key = args.first
|
41
|
+
result = @members[key] if key.present?
|
42
|
+
|
43
|
+
return result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'redis'
|
3
|
+
|
4
|
+
module RedisRds
|
5
|
+
# Configuration defaults
|
6
|
+
@config = {
|
7
|
+
host: 'localhost',
|
8
|
+
db: 1,
|
9
|
+
port: 6379,
|
10
|
+
timeout: 30,
|
11
|
+
thread_safe: true,
|
12
|
+
# FIXME: add username and password
|
13
|
+
namespace: 'testns',
|
14
|
+
connection: nil
|
15
|
+
}
|
16
|
+
|
17
|
+
@valid_config_keys = @config.keys
|
18
|
+
|
19
|
+
# Configure through hash
|
20
|
+
def self.configure(opts = {})
|
21
|
+
opts.each { |k, v| @config[k.to_sym] = v if @valid_config_keys.include? k.to_sym }
|
22
|
+
|
23
|
+
if opts[:connection].present?
|
24
|
+
connection = opts[:connection]
|
25
|
+
else
|
26
|
+
config[:db] = config[:db].to_i
|
27
|
+
connection = Redis.new(config)
|
28
|
+
end
|
29
|
+
|
30
|
+
RedisRds::Object.configure(connection: connection, namespace: opts[:namespace])
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.config
|
34
|
+
@config
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class ExpirableHash < RedisRds::Hash
|
3
|
+
EXPIRY_KEY_SUFFIX = '__expiry__'.freeze
|
4
|
+
|
5
|
+
def get(key)
|
6
|
+
result = nil
|
7
|
+
value, expires_at = connection.hmget(@redis_key, key, expiry_key(key))
|
8
|
+
if expired?(expires_at)
|
9
|
+
remove(key)
|
10
|
+
else
|
11
|
+
result = value
|
12
|
+
end
|
13
|
+
|
14
|
+
return result
|
15
|
+
end
|
16
|
+
|
17
|
+
def set(key, value)
|
18
|
+
connection.multi do |redis|
|
19
|
+
redis.hset(@redis_key, key, value)
|
20
|
+
redis.hdel(@redis_key, expiry_key(key))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def setex(key, value, expiry)
|
25
|
+
expires_at = Time.now.to_i + expiry
|
26
|
+
connection.hmset(@redis_key, key, value, expiry_key(key), expires_at)
|
27
|
+
end
|
28
|
+
|
29
|
+
def expiry_key(key)
|
30
|
+
return "#{key}#{EXPIRY_KEY_SUFFIX}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove(key)
|
34
|
+
connection.multi do |redis|
|
35
|
+
redis.hdel(@redis_key, key)
|
36
|
+
redis.hdel(@redis_key, expiry_key(key))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def all
|
41
|
+
hash = ::Hash[super().group_by do |key, _value|
|
42
|
+
if key.ends_with?(EXPIRY_KEY_SUFFIX)
|
43
|
+
key[0...(key.length - EXPIRY_KEY_SUFFIX.length)]
|
44
|
+
else
|
45
|
+
key
|
46
|
+
end
|
47
|
+
end.map { |key, values| [key, values.map(&:second)] }]
|
48
|
+
|
49
|
+
expired, valid = hash.partition { |_key, values| expired?(values.second) }
|
50
|
+
expired.each { |key, _| remove(key) }
|
51
|
+
|
52
|
+
return ::Hash[valid.map { |key, values| [key, values.first] }]
|
53
|
+
end
|
54
|
+
|
55
|
+
def expired?(expires_at)
|
56
|
+
return false if expires_at.nil?
|
57
|
+
return Time.now.to_i >= expires_at.to_i
|
58
|
+
end
|
59
|
+
private :expired?
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class Hash < RedisRds::Object
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def get(key)
|
6
|
+
return connection.hget(@redis_key, key)
|
7
|
+
end
|
8
|
+
alias [] get
|
9
|
+
|
10
|
+
def set(key, value)
|
11
|
+
return connection.hset(@redis_key, key, value)
|
12
|
+
end
|
13
|
+
alias []= set
|
14
|
+
|
15
|
+
def mset(*args)
|
16
|
+
return connection.hmset(@redis_key, *args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def mget(*_args)
|
20
|
+
return connection.hmget(@redis_key, *arg)
|
21
|
+
end
|
22
|
+
|
23
|
+
def setnx(key, value)
|
24
|
+
return connection.hsetnx(@redis_key, key, value)
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove(key)
|
28
|
+
return connection.hdel(@redis_key, key)
|
29
|
+
end
|
30
|
+
|
31
|
+
def incrby(key, increment)
|
32
|
+
return connection.hincrby(@redis_key, key, increment)
|
33
|
+
end
|
34
|
+
|
35
|
+
def key?(key)
|
36
|
+
return connection.hexists(@redis_key, key)
|
37
|
+
end
|
38
|
+
|
39
|
+
def incr(key)
|
40
|
+
return incrby(key, 1)
|
41
|
+
end
|
42
|
+
|
43
|
+
def decr(key)
|
44
|
+
return incrby(key, -1)
|
45
|
+
end
|
46
|
+
|
47
|
+
def decrby(key, decrement)
|
48
|
+
return incrby(key, -decrement)
|
49
|
+
end
|
50
|
+
|
51
|
+
def all
|
52
|
+
return (getall || {}).with_indifferent_access
|
53
|
+
end
|
54
|
+
|
55
|
+
def getall
|
56
|
+
return connection.hgetall(@redis_key)
|
57
|
+
end
|
58
|
+
|
59
|
+
def values
|
60
|
+
return all.values
|
61
|
+
end
|
62
|
+
|
63
|
+
def keys
|
64
|
+
return all.keys
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_json
|
68
|
+
return all.to_json
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO: Implement lazy enumerator
|
72
|
+
def each(&block)
|
73
|
+
return all.each(&block)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class List < RedisRds::Object
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def size
|
6
|
+
return connection.llen(@redis_key)
|
7
|
+
end
|
8
|
+
|
9
|
+
def empty?
|
10
|
+
return self.size == 0 # rubocop:disable Style/ZeroLengthPredicate
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(start, stop = -1)
|
14
|
+
return connection.lrange(@redis_key, start, stop)
|
15
|
+
end
|
16
|
+
|
17
|
+
def rpush(elems)
|
18
|
+
return connection.rpush(@redis_key, Array.wrap(elems))
|
19
|
+
end
|
20
|
+
|
21
|
+
def lpush(elems)
|
22
|
+
return connection.lpush(@redis_key, Array.wrap(elems))
|
23
|
+
end
|
24
|
+
|
25
|
+
def lpop(length = 1, force = false)
|
26
|
+
lua_script = "
|
27
|
+
local length = tonumber(ARGV[1]);
|
28
|
+
if (ARGV[2] ~= 'true' or redis.call('llen', KEYS[1])>=length) then
|
29
|
+
local result = redis.call('lrange', KEYS[1], 0, length - 1);
|
30
|
+
redis.call('ltrim', KEYS[1], length, - 1);
|
31
|
+
return result
|
32
|
+
else return ''
|
33
|
+
end"
|
34
|
+
result = connection.eval(lua_script, [@redis_key], [length, force])
|
35
|
+
result = [] if result.blank?
|
36
|
+
|
37
|
+
return result
|
38
|
+
end
|
39
|
+
|
40
|
+
def each(&block)
|
41
|
+
return get(0).each(&block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def clear
|
45
|
+
# if start > end redis clears the list
|
46
|
+
# http://redis.io/commands/ltrim
|
47
|
+
return connection.ltrim(@redis_key, 1, 0)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class Mutex < RedisRds::String
|
3
|
+
DEFAULT_EXPIRY = 60.seconds
|
4
|
+
|
5
|
+
attr_reader :id, :expiry
|
6
|
+
|
7
|
+
def initialize(id, expiry = DEFAULT_EXPIRY, owner = '')
|
8
|
+
super("#{namespace}:mutex:#{id}")
|
9
|
+
|
10
|
+
@id = id
|
11
|
+
@expiry = expiry
|
12
|
+
@owner = owner.blank? ? generate_owner : owner
|
13
|
+
end
|
14
|
+
|
15
|
+
def lock
|
16
|
+
connection.set(@redis_key, @owner, ex: @expiry, nx: true)
|
17
|
+
return locked?
|
18
|
+
end
|
19
|
+
|
20
|
+
def locked?
|
21
|
+
return connection.get(@redis_key) == @owner
|
22
|
+
end
|
23
|
+
alias owned? locked?
|
24
|
+
|
25
|
+
def release
|
26
|
+
self.delete if owned?
|
27
|
+
end
|
28
|
+
|
29
|
+
def serialize
|
30
|
+
[@id, @expiry, @owner]
|
31
|
+
end
|
32
|
+
|
33
|
+
def synchronize
|
34
|
+
if self.lock
|
35
|
+
begin
|
36
|
+
yield if block_given?
|
37
|
+
ensure
|
38
|
+
self.release
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def generate_owner
|
44
|
+
now = Time.now.to_f
|
45
|
+
random = Random.new(now)
|
46
|
+
return Digest::MD5.hexdigest(random.rand(now).to_s)
|
47
|
+
end
|
48
|
+
private :generate_owner
|
49
|
+
|
50
|
+
class << self
|
51
|
+
def unserialize(serialized)
|
52
|
+
return self.new(*serialized)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class NestedHash < RedisRds::Hash
|
3
|
+
SEPARATOR = ':'.freeze
|
4
|
+
|
5
|
+
def setnx(*keys, value)
|
6
|
+
return super(format_key(keys), value)
|
7
|
+
end
|
8
|
+
|
9
|
+
def incrby(*keys, increment)
|
10
|
+
return super(format_key(keys), increment)
|
11
|
+
end
|
12
|
+
|
13
|
+
def key?(_key)
|
14
|
+
return super(format_key(keys))
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(*keys)
|
18
|
+
super(format_key(keys))
|
19
|
+
end
|
20
|
+
|
21
|
+
def set(*keys, value)
|
22
|
+
super(format_key(keys), value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def setex(*keys, value, expiry)
|
26
|
+
super(format_key(keys), value, expiry)
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove(*keys)
|
30
|
+
super(format_key(keys))
|
31
|
+
end
|
32
|
+
|
33
|
+
def format_key(keys)
|
34
|
+
return Array.wrap(keys).join(SEPARATOR)
|
35
|
+
end
|
36
|
+
private :format_key
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class Object
|
3
|
+
attr_accessor :redis_key
|
4
|
+
|
5
|
+
def initialize(redis_key)
|
6
|
+
@redis_key = format_redis_key(redis_key)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.flushdb
|
10
|
+
connection.flushdb
|
11
|
+
end
|
12
|
+
|
13
|
+
@@namespace = nil
|
14
|
+
@@connection = nil
|
15
|
+
def self.configure(options)
|
16
|
+
@@namespace = options[:namespace]
|
17
|
+
@@connection = options[:connection]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.connection
|
21
|
+
return @@connection
|
22
|
+
end
|
23
|
+
|
24
|
+
def connection
|
25
|
+
return @@connection
|
26
|
+
end
|
27
|
+
|
28
|
+
def namespace
|
29
|
+
return @@namespace
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete
|
33
|
+
return connection.del(@redis_key)
|
34
|
+
end
|
35
|
+
|
36
|
+
def type
|
37
|
+
return connection.type(@redis_key)
|
38
|
+
end
|
39
|
+
|
40
|
+
def expire(expiry)
|
41
|
+
return connection.expire(@redis_key, expiry)
|
42
|
+
end
|
43
|
+
|
44
|
+
def expireat(timestamp)
|
45
|
+
return connection.expireat(@redis_key, timestamp.to_i)
|
46
|
+
end
|
47
|
+
|
48
|
+
def dump
|
49
|
+
return connection.dump(@redis_key)
|
50
|
+
end
|
51
|
+
|
52
|
+
def exists?
|
53
|
+
return connection.exists(@redis_key)
|
54
|
+
end
|
55
|
+
|
56
|
+
def persist
|
57
|
+
return connection.persist(@redis_key)
|
58
|
+
end
|
59
|
+
|
60
|
+
def ttl
|
61
|
+
return connection.ttl(@redis_key)
|
62
|
+
end
|
63
|
+
|
64
|
+
def pttl
|
65
|
+
return connection.pttl(@redis_key)
|
66
|
+
end
|
67
|
+
|
68
|
+
def format_redis_key(key)
|
69
|
+
key = "#{namespace}:#{key}" unless key.start_with?(namespace)
|
70
|
+
return key
|
71
|
+
end
|
72
|
+
private :format_redis_key
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class Set < RedisRds::Object
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def add(item)
|
6
|
+
return connection.sadd(@redis_key, item)
|
7
|
+
end
|
8
|
+
alias << add
|
9
|
+
alias push add
|
10
|
+
|
11
|
+
def merge(enumerable)
|
12
|
+
lua_script = "
|
13
|
+
local result = 0;
|
14
|
+
for i, item in ipairs(ARGV) do
|
15
|
+
result = result + redis.call('sadd', KEYS[1], item);
|
16
|
+
end
|
17
|
+
return result;"
|
18
|
+
result = connection.eval(lua_script, [@redis_key], enumerable.entries)
|
19
|
+
result = [] if result.blank?
|
20
|
+
|
21
|
+
return result
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove(item)
|
25
|
+
return connection.srem(@redis_key, item)
|
26
|
+
end
|
27
|
+
|
28
|
+
def all
|
29
|
+
return ::Set.new(connection.smembers(@redis_key)).to_a
|
30
|
+
end
|
31
|
+
|
32
|
+
def consume
|
33
|
+
lua_script = "
|
34
|
+
local result = redis.call('smembers', KEYS[1]);
|
35
|
+
redis.call('del', KEYS[1]);
|
36
|
+
return result;"
|
37
|
+
result = connection.eval(lua_script, [@redis_key])
|
38
|
+
result = [] if result.blank?
|
39
|
+
|
40
|
+
return ::Set.new(Array.wrap(result).compact).to_a
|
41
|
+
end
|
42
|
+
|
43
|
+
def size
|
44
|
+
return connection.scard(@redis_key)
|
45
|
+
end
|
46
|
+
|
47
|
+
def include?(object)
|
48
|
+
return connection.sismember(@redis_key, object)
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_json
|
52
|
+
return all.to_json
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO: Implement lazy enumerator
|
56
|
+
def each(&block)
|
57
|
+
return all.each(&block)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class SortedSet < RedisRds::Object
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def add(score, item)
|
6
|
+
return connection.zadd(@redis_key, score, item)
|
7
|
+
end
|
8
|
+
|
9
|
+
def push(item)
|
10
|
+
index = size
|
11
|
+
return add(index, item)
|
12
|
+
end
|
13
|
+
alias << push
|
14
|
+
|
15
|
+
def all
|
16
|
+
return connection.zrange(@redis_key, 0, -1).to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
def empty?
|
20
|
+
return size == 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def size
|
24
|
+
return connection.zcard(@redis_key)
|
25
|
+
end
|
26
|
+
|
27
|
+
def include?(item)
|
28
|
+
return !index_of(item).nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def remove(item)
|
32
|
+
return connection.zrem(@redis_key, item)
|
33
|
+
end
|
34
|
+
|
35
|
+
def remove_by_score(min, max)
|
36
|
+
return connection.zremrangebyscore(@redis_key, min, max)
|
37
|
+
end
|
38
|
+
|
39
|
+
def range(min, max, order: :asc)
|
40
|
+
case order
|
41
|
+
when :desc
|
42
|
+
connection.zrevrange(@redis_key, min, max)
|
43
|
+
else
|
44
|
+
connection.zrange(@redis_key, min, max)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def index_of(item)
|
49
|
+
return connection.zrank(@redis_key, item)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_json
|
53
|
+
return all.to_json
|
54
|
+
end
|
55
|
+
|
56
|
+
# TODO: Implement lazy enumerator
|
57
|
+
def each(&block)
|
58
|
+
return all.each(&block)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class SortedStringSet < RedisRds::SortedSet
|
3
|
+
DEFAULT_SCORE = 0
|
4
|
+
|
5
|
+
def add(item)
|
6
|
+
super(DEFAULT_SCORE, item)
|
7
|
+
end
|
8
|
+
|
9
|
+
def push(item)
|
10
|
+
return add(item)
|
11
|
+
end
|
12
|
+
|
13
|
+
def all
|
14
|
+
return range('-', '+').to_a
|
15
|
+
end
|
16
|
+
|
17
|
+
def remove(item)
|
18
|
+
return connection.zrem(@redis_key, item)
|
19
|
+
end
|
20
|
+
|
21
|
+
def range(min, max)
|
22
|
+
min, max = [min, max].map do |r|
|
23
|
+
next(r) if ['-', '+'].include?(r) || r.start_with?('[') || r.start_with?('(')
|
24
|
+
"[#{r}"
|
25
|
+
end
|
26
|
+
|
27
|
+
return connection.zrangebylex(@redis_key, min, max)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RedisRds
|
2
|
+
class String < RedisRds::Object
|
3
|
+
def get
|
4
|
+
return connection.get(@redis_key)
|
5
|
+
end
|
6
|
+
|
7
|
+
def set(value)
|
8
|
+
return connection.set(@redis_key, value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def setex(value, expiry)
|
12
|
+
return connection.setex(@redis_key, expiry, value)
|
13
|
+
end
|
14
|
+
|
15
|
+
def append(suffix)
|
16
|
+
return connection.append(@redis_key, suffix)
|
17
|
+
end
|
18
|
+
|
19
|
+
def incr
|
20
|
+
return connection.incr(@redis_key)
|
21
|
+
end
|
22
|
+
|
23
|
+
def incrby(increment)
|
24
|
+
return connection.incrby(@redis_key, increment)
|
25
|
+
end
|
26
|
+
|
27
|
+
def length
|
28
|
+
return connection.strlen(@redis_key)
|
29
|
+
end
|
30
|
+
|
31
|
+
def setnx(value)
|
32
|
+
return connection.setnx(@redis_key, value)
|
33
|
+
end
|
34
|
+
|
35
|
+
def decr
|
36
|
+
return connection.decr(@redis_key)
|
37
|
+
end
|
38
|
+
|
39
|
+
def decrby(decrement)
|
40
|
+
return connection.decrby(@redis_key, decrement)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/redis_rds.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
require 'redis_rds/version'
|
5
|
+
|
6
|
+
require 'redis_rds/config'
|
7
|
+
require 'redis_rds/composite'
|
8
|
+
require 'redis_rds/object'
|
9
|
+
require 'redis_rds/string'
|
10
|
+
require 'redis_rds/hash'
|
11
|
+
require 'redis_rds/expirable_hash'
|
12
|
+
require 'redis_rds/list'
|
13
|
+
require 'redis_rds/mutex'
|
14
|
+
require 'redis_rds/nested_hash'
|
15
|
+
require 'redis_rds/set'
|
16
|
+
require 'redis_rds/sorted_set'
|
17
|
+
require 'redis_rds/sorted_string_set'
|
18
|
+
|
19
|
+
module RedisRds
|
20
|
+
end
|
data/redis_rds.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'redis_rds/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'redis_rds'
|
8
|
+
spec.version = RedisRds::VERSION
|
9
|
+
spec.authors = ['Checkitmobile GmbH']
|
10
|
+
spec.email = ['support@barcoo.com']
|
11
|
+
|
12
|
+
spec.summary = 'Ruby data structures stored in Redis.'
|
13
|
+
spec.description = 'RedisRds provides Ruby interfaces for data structures like String or Hash stored in Redis.'
|
14
|
+
spec.homepage = 'https://github.com/barcoo/redis_rds'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'redis', '~> 3.2'
|
23
|
+
spec.add_dependency 'activesupport', '~> 4'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.12'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
28
|
+
spec.add_development_dependency 'pry'
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
{
|
2
|
+
"folders":
|
3
|
+
[
|
4
|
+
{
|
5
|
+
"path": ".",
|
6
|
+
"folder_exclude_patterns": ["log", "tmp"],
|
7
|
+
"file_exclude_patterns": [".rubocop-*", "*.md-u", "*~"]
|
8
|
+
}
|
9
|
+
],
|
10
|
+
"settings":
|
11
|
+
{
|
12
|
+
"translate_tabs_to_spaces": true
|
13
|
+
},
|
14
|
+
"SublimeLinter": {
|
15
|
+
"linters": {
|
16
|
+
"rubocop": {
|
17
|
+
"@disable": false,
|
18
|
+
"args": ["--config", "${project}/.rubocop.yml"],
|
19
|
+
"excludes": []
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redis_rds
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Checkitmobile GmbH
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: redis
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.12'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.12'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: RedisRds provides Ruby interfaces for data structures like String or
|
98
|
+
Hash stored in Redis.
|
99
|
+
email:
|
100
|
+
- support@barcoo.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".coveralls.yml"
|
106
|
+
- ".gitignore"
|
107
|
+
- ".rubocop.yml"
|
108
|
+
- ".travis.yml"
|
109
|
+
- CHANGELOG.md
|
110
|
+
- Gemfile
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- bin/console
|
115
|
+
- bin/setup
|
116
|
+
- doc/ROADMAP.md
|
117
|
+
- lib/redis_rds.rb
|
118
|
+
- lib/redis_rds/composite.rb
|
119
|
+
- lib/redis_rds/config.rb
|
120
|
+
- lib/redis_rds/expirable_hash.rb
|
121
|
+
- lib/redis_rds/hash.rb
|
122
|
+
- lib/redis_rds/list.rb
|
123
|
+
- lib/redis_rds/mutex.rb
|
124
|
+
- lib/redis_rds/nested_hash.rb
|
125
|
+
- lib/redis_rds/object.rb
|
126
|
+
- lib/redis_rds/set.rb
|
127
|
+
- lib/redis_rds/sorted_set.rb
|
128
|
+
- lib/redis_rds/sorted_string_set.rb
|
129
|
+
- lib/redis_rds/string.rb
|
130
|
+
- lib/redis_rds/version.rb
|
131
|
+
- redis_rds.gemspec
|
132
|
+
- redis_rds.sublime-project
|
133
|
+
homepage: https://github.com/barcoo/redis_rds
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
metadata: {}
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 2.6.6
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: Ruby data structures stored in Redis.
|
157
|
+
test_files: []
|