redstruct 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +42 -0
- data/Rakefile +18 -0
- data/lib/redstruct/configuration.rb +14 -0
- data/lib/redstruct/connection.rb +29 -0
- data/lib/redstruct/error.rb +5 -0
- data/lib/redstruct/factory/creation.rb +95 -0
- data/lib/redstruct/factory/deserialization.rb +7 -0
- data/lib/redstruct/factory.rb +45 -0
- data/lib/redstruct/hls/lock.rb +175 -0
- data/lib/redstruct/hls/queue.rb +29 -0
- data/lib/redstruct/hls.rb +2 -0
- data/lib/redstruct/types/base.rb +47 -0
- data/lib/redstruct/types/counter.rb +65 -0
- data/lib/redstruct/types/hash.rb +72 -0
- data/lib/redstruct/types/list.rb +78 -0
- data/lib/redstruct/types/script.rb +56 -0
- data/lib/redstruct/types/set.rb +96 -0
- data/lib/redstruct/types/sorted_set.rb +15 -0
- data/lib/redstruct/types/string.rb +64 -0
- data/lib/redstruct/types/struct.rb +41 -0
- data/lib/redstruct/utils/coercion.rb +33 -0
- data/lib/redstruct/utils/inspectable.rb +21 -0
- data/lib/redstruct/utils/scriptable.rb +21 -0
- data/lib/redstruct/version.rb +3 -0
- data/lib/redstruct/yard/defscript_handler.rb +32 -0
- data/lib/redstruct.rb +65 -0
- data/test/redstruct/restruct_test.rb +4 -0
- data/test/test_helper.rb +4 -0
- metadata +145 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
module Redstruct
|
2
|
+
module Types
|
3
|
+
class List < Redstruct::Types::Struct
|
4
|
+
include Redstruct::Utils::Scriptable
|
5
|
+
|
6
|
+
def clear
|
7
|
+
delete
|
8
|
+
end
|
9
|
+
|
10
|
+
def empty?
|
11
|
+
return !exists?
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](index)
|
15
|
+
return self.connection.lindex(@key, index.to_i)
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(index, value)
|
19
|
+
return self.connection.lset(@key, index.to_i, value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def append(*elements, max: 0)
|
23
|
+
max = max.to_i
|
24
|
+
return self.connection.rpush(@key, elements) if max <= 0
|
25
|
+
return push_and_trim_script(keys: @key, argv: [max - 1, 0] + elements)
|
26
|
+
end
|
27
|
+
|
28
|
+
def prepend(*elements, max: nil)
|
29
|
+
max = max.to_i
|
30
|
+
return self.connection.lpush(@key, elements) if max <= 0
|
31
|
+
return push_and_trim_script(keys: @key, argv: [max - 1, 1] + elements)
|
32
|
+
end
|
33
|
+
|
34
|
+
def pop(timeout: nil)
|
35
|
+
options = {}
|
36
|
+
options[:timeout] = timeout.to_i unless timeout.nil?
|
37
|
+
return self.connection.blpop(@key, options)&.last
|
38
|
+
end
|
39
|
+
|
40
|
+
def remove(value, count: 1)
|
41
|
+
count = [1, count.to_i].max
|
42
|
+
self.connection.lrem(@key, count, value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def size
|
46
|
+
return self.connection.llen(@key)
|
47
|
+
end
|
48
|
+
|
49
|
+
def slice(start = 0, length = -1)
|
50
|
+
return self.connection.lrange(@key, start.to_i, length.to_i)
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_a
|
54
|
+
return slice(0, -1)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Appends or prepends (argv[1]) a number of items (argv[2]) to a list (keys[1]),
|
58
|
+
# then trims it out to size (argv[3])
|
59
|
+
# @param [Array<(::String)>] keys First key should be the key to the list to prepend to and resize
|
60
|
+
# @param [Array<(Fixnum, Fixnum, Array<::String>)>] argv The maximum size of the list; if 1, will lpush, otherwise rpush; the list of items to prepend
|
61
|
+
# @return [Fixnum] The length of the list after the operation
|
62
|
+
defscript :push_and_trim_script, <<~LUA
|
63
|
+
local max = tonumber(table.remove(ARGV, 1))
|
64
|
+
local prepend = tonumber(table.remove(ARGV, 1)) == 1
|
65
|
+
local push = prepend and 'lpush' or 'rpush'
|
66
|
+
|
67
|
+
local size = redis.call(push, KEYS[1], unpack(ARGV))
|
68
|
+
if size > max then
|
69
|
+
redis.call('ltrim', KEYS[1], 0, max)
|
70
|
+
size = max + 1
|
71
|
+
end
|
72
|
+
|
73
|
+
return size
|
74
|
+
LUA
|
75
|
+
protected :push_and_trim_script
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module Redstruct
|
4
|
+
module Types
|
5
|
+
# It is recommended you flush your script cache on the redis server every once in a while
|
6
|
+
class Script < Redstruct::Types::Base
|
7
|
+
ERROR_MESSAGE_PREFIX = 'NOSCRIPT'.freeze
|
8
|
+
|
9
|
+
# @return [::String] The Lua script to evaluate
|
10
|
+
attr_reader :script
|
11
|
+
|
12
|
+
def initialize(script:, **options)
|
13
|
+
script = script&.strip
|
14
|
+
raise(Redstruct::Error, 'No source script given') if script.empty?
|
15
|
+
|
16
|
+
super(**options)
|
17
|
+
self.script = script
|
18
|
+
end
|
19
|
+
|
20
|
+
def script=(script)
|
21
|
+
@sha1 = nil
|
22
|
+
@script = script.dup.freeze
|
23
|
+
end
|
24
|
+
|
25
|
+
def sha1
|
26
|
+
return @sha1 ||= begin
|
27
|
+
Digest::SHA1.hexdigest(@script)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def exists?
|
32
|
+
return self.connection.script(:exists, self.sha1)
|
33
|
+
end
|
34
|
+
|
35
|
+
def load
|
36
|
+
@sha1 = self.connection.script(:load, @script)
|
37
|
+
return @sha1
|
38
|
+
end
|
39
|
+
|
40
|
+
def eval(keys:, argv:)
|
41
|
+
keys = [keys] unless keys.is_a?(Array)
|
42
|
+
argv = [argv] unless argv.is_a?(Array)
|
43
|
+
self.connection.evalsha(self.sha1, keys, argv)
|
44
|
+
rescue Redis::CommandError => err
|
45
|
+
raise unless err.message.start_with?(ERROR_MESSAGE_PREFIX)
|
46
|
+
self.connection.eval(@script, keys, argv)
|
47
|
+
end
|
48
|
+
|
49
|
+
# :nocov:
|
50
|
+
def inspectable_attributes
|
51
|
+
return super.merge(sha1: self.sha1, script: @script.slice(0, 20))
|
52
|
+
end
|
53
|
+
# :nocov:
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Redstruct
|
2
|
+
module Types
|
3
|
+
# Note: keep in mind Redis converts everything to a string on the DB side
|
4
|
+
class Set < Redstruct::Types::Struct
|
5
|
+
def clear
|
6
|
+
delete
|
7
|
+
end
|
8
|
+
|
9
|
+
def random(count: 1)
|
10
|
+
return self.connection.srandmember(@key, count.to_i)
|
11
|
+
end
|
12
|
+
|
13
|
+
def empty?
|
14
|
+
return !exists?
|
15
|
+
end
|
16
|
+
|
17
|
+
def contain?(member)
|
18
|
+
return self.connection.sismember(@key, member)
|
19
|
+
end
|
20
|
+
alias_method :include?, :contain?
|
21
|
+
|
22
|
+
def to_a
|
23
|
+
return self.connection.smembers(@key)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add(*members)
|
27
|
+
return self.connection.sadd(@key, members)
|
28
|
+
end
|
29
|
+
alias_method :<<, :add
|
30
|
+
|
31
|
+
def size
|
32
|
+
return self.connection.scard(@key).to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def -(other)
|
36
|
+
return ::Set.new(self.connection.sdiff(@key, other.key))
|
37
|
+
end
|
38
|
+
|
39
|
+
def +(other)
|
40
|
+
return ::Set.new(self.connection.sunion(@key, other.key))
|
41
|
+
end
|
42
|
+
|
43
|
+
def |(other)
|
44
|
+
return ::Set.new(self.connection.sinter(@key, other.key))
|
45
|
+
end
|
46
|
+
|
47
|
+
def difference(other, dest: nil)
|
48
|
+
destination = coerce_destination(dest)
|
49
|
+
return self - other if destination.nil?
|
50
|
+
|
51
|
+
self.connection.sdiffstore(destination.key, @key, other.key)
|
52
|
+
return destination
|
53
|
+
end
|
54
|
+
|
55
|
+
def intersection(other, dest: nil)
|
56
|
+
destination = coerce_destination(dest)
|
57
|
+
return self - other if destination.nil?
|
58
|
+
|
59
|
+
self.connection.sinterstore(destination.key, @key, other.key)
|
60
|
+
return destination
|
61
|
+
end
|
62
|
+
|
63
|
+
def union(other, dest: nil)
|
64
|
+
destination = coerce_destination(dest)
|
65
|
+
return self - other if destination.nil?
|
66
|
+
|
67
|
+
self.connection.sunionstore(destination.key, @key, other.key)
|
68
|
+
return destination
|
69
|
+
end
|
70
|
+
|
71
|
+
def pop(count: 1)
|
72
|
+
return self.connection.spop(@key, count.to_i)
|
73
|
+
end
|
74
|
+
|
75
|
+
def remove(*members)
|
76
|
+
return self.connection.srem(@key, *members)
|
77
|
+
end
|
78
|
+
|
79
|
+
def each(options = {}, &block)
|
80
|
+
return self.connection.sscan_each(@key, options, &block)
|
81
|
+
end
|
82
|
+
|
83
|
+
def coerce_destination(dest)
|
84
|
+
return case dest
|
85
|
+
when ::String
|
86
|
+
@factory.set(dest)
|
87
|
+
when self.class
|
88
|
+
dest
|
89
|
+
else
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
private :coerce_destination
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Redstruct
|
2
|
+
module Types
|
3
|
+
class SortedSet < Redstruct::Types::Struct
|
4
|
+
DEFAULT_SCORE = 1.0
|
5
|
+
|
6
|
+
def add(options = {}, *items)
|
7
|
+
defaults = { nx: false, xx: false, ch: false }
|
8
|
+
end
|
9
|
+
|
10
|
+
def <<(item)
|
11
|
+
return self.connection.zadd(@key, DEFAULT_SCORE, item)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Redstruct
|
2
|
+
module Types
|
3
|
+
class String < Redstruct::Types::Struct
|
4
|
+
include Redstruct::Utils::Scriptable, Redstruct::Utils::Coercion
|
5
|
+
|
6
|
+
# @return [::String] The string value stored in the database
|
7
|
+
def get
|
8
|
+
return self.connection.get(@key)
|
9
|
+
end
|
10
|
+
|
11
|
+
# @param [Object] value The object to store; note, it will be stored using a string representation
|
12
|
+
# @param [Integer] expiry The expiry time in seconds; if nil, will never expire
|
13
|
+
# @param [Boolean] nx Not Exists: if true, will not set the key if it already existed
|
14
|
+
# @param [Boolean] xx Already Exists: if true, will set the key only if it already existed
|
15
|
+
# @return [Boolean] True if set, false otherwise
|
16
|
+
def set(value, expiry: nil, nx: nil, xx: nil)
|
17
|
+
options = {}
|
18
|
+
options[:ex] = expiry.to_i unless expiry.nil?
|
19
|
+
options[:nx] = nx unless nx.nil?
|
20
|
+
options[:xx] = xx unless xx.nil?
|
21
|
+
|
22
|
+
self.connection.set(@key, value, options) == 'OK'
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [::String] value The value to compare with
|
26
|
+
# @return [Boolean] True if deleted, false otherwise
|
27
|
+
def delete_if_equals(value)
|
28
|
+
coerce_bool(delete_if_equals_script(keys: @key, argv: value))
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [Object] value The object to store; note, it will be stored using a string representation
|
32
|
+
# @return [::String] The old value before setting it
|
33
|
+
def getset(value)
|
34
|
+
self.connection.getset(@key, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Fixnum] The length of the string
|
38
|
+
def length
|
39
|
+
self.connection.strlen(@key)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param [Fixnum] start Starting index of the slice
|
43
|
+
# @param [Fixnum] length Length of the slice; negative numbers start counting from the right (-1 = end)
|
44
|
+
# @return [Array<::String>] The requested slice from <start> with length <length>
|
45
|
+
def slice(start = 0, length = -1)
|
46
|
+
length = start + length if length >= 0
|
47
|
+
return self.connection.getrange(@key, start, length)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Deletes the key (keys[1]) iff the value is equal to argv[1].
|
51
|
+
# @param [Array<(::String)>] keys The key to delete
|
52
|
+
# @param [Array<(::String)>] argv The value to compare with
|
53
|
+
# @return [Fixnum] 1 if deleted, 0 otherwise
|
54
|
+
defscript :delete_if_equals_script, <<~LUA
|
55
|
+
local deleted = false
|
56
|
+
if redis.call("get", KEYS[1]) == ARGV[1] then
|
57
|
+
deleted = redis.call("del", KEYS[1])
|
58
|
+
end
|
59
|
+
|
60
|
+
return deleted
|
61
|
+
LUA
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Redstruct
|
4
|
+
module Types
|
5
|
+
class Struct < Redstruct::Types::Base
|
6
|
+
include Redstruct::Utils::Inspectable
|
7
|
+
|
8
|
+
# @return [Boolean] Returns true if it exists in redis, false otherwise
|
9
|
+
def exists?
|
10
|
+
return self.connection.exists(@key)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Fixnum] 0 if nothing was deleted in the DB, 1 if it was
|
14
|
+
def delete
|
15
|
+
self.connection.del(@key)
|
16
|
+
end
|
17
|
+
|
18
|
+
def expire(ttl)
|
19
|
+
self.connection.expire(@key, ttl)
|
20
|
+
end
|
21
|
+
|
22
|
+
def expire_at(time)
|
23
|
+
self.connection.expire_at(@key, time.to_i)
|
24
|
+
end
|
25
|
+
|
26
|
+
def persist
|
27
|
+
self.connection.persist(@key)
|
28
|
+
end
|
29
|
+
|
30
|
+
def type
|
31
|
+
self.connection.type(@key)
|
32
|
+
end
|
33
|
+
|
34
|
+
# :nocov:
|
35
|
+
def inspectable_attributes
|
36
|
+
super.merge(key: @key)
|
37
|
+
end
|
38
|
+
# :nocov:
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Redstruct
|
2
|
+
module Utils
|
3
|
+
# Coercion utilities to map Redis replies to Ruby types, or vice-versa
|
4
|
+
module Coercion
|
5
|
+
# Coerces the value into an array.
|
6
|
+
# Returns the value if it is already an array (or subclass)
|
7
|
+
# Returns value.to_a if it responds to to_a
|
8
|
+
# Returns [value] otherwise
|
9
|
+
# @param [Object] value The value to coerce
|
10
|
+
# @return [Array] The coerced value
|
11
|
+
def coerce_array(value)
|
12
|
+
return [] if value.nil?
|
13
|
+
return value if value.is_a?(Array)
|
14
|
+
return value.to_a if value.respond_to?(:to_a)
|
15
|
+
return [value]
|
16
|
+
end
|
17
|
+
module_function :coerce_array
|
18
|
+
|
19
|
+
# Coerces an object into a boolean:
|
20
|
+
# If nil or 0 (after .to_i) => false
|
21
|
+
# True otherwise
|
22
|
+
# @param [Object] value The object to coerce into a bool
|
23
|
+
# @return [Boolean] Coerced value
|
24
|
+
def coerce_bool(value)
|
25
|
+
return false if value.nil?
|
26
|
+
return false if value.to_i == 0
|
27
|
+
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
module_function :coerce_bool
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Redstruct
|
2
|
+
module Utils
|
3
|
+
module Inspectable
|
4
|
+
def inspect
|
5
|
+
attributes = inspectable_attributes.map do |key, value|
|
6
|
+
"#{key}: <#{value.inspect}>"
|
7
|
+
end
|
8
|
+
|
9
|
+
return "#{self.class.name}: #{attributes.join(', ')}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspectable_attributes
|
13
|
+
{}
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
return inspect
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Redstruct
|
2
|
+
module Utils
|
3
|
+
module Scriptable
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def defscript(id, source)
|
10
|
+
constant = "SCRIPT_SOURCE_#{id.upcase}"
|
11
|
+
class_eval <<~METHOD, __FILE__, __LINE__ + 1
|
12
|
+
#{constant} = { id: '#{id}'.freeze, source: %(#{source}).freeze }.freeze
|
13
|
+
def #{id}(keys: [], argv: [])
|
14
|
+
return @factory.script(#{constant}[:id], #{constant}[:source]).eval(keys: keys, argv: argv)
|
15
|
+
end
|
16
|
+
METHOD
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Redstruct
|
2
|
+
class DefscriptHandler < YARD::Handlers::Ruby::Base
|
3
|
+
GROUP_NAME = 'Lua Scripts'.freeze
|
4
|
+
|
5
|
+
handles method_call(:defscript)
|
6
|
+
namespace_only
|
7
|
+
|
8
|
+
process do
|
9
|
+
method_name = statement.parameters[0].jump(:ident).source
|
10
|
+
method_body = strip_heredoc(statement.parameters[1].source)
|
11
|
+
|
12
|
+
script = YARD::CodeObjects::MethodObject.new(namespace, method_name, scope)
|
13
|
+
script.parameters = [['keys', []], ['argv', []]]
|
14
|
+
script.source = method_body
|
15
|
+
script.source_type = :lua
|
16
|
+
script.dynamic = true
|
17
|
+
script.group = GROUP_NAME
|
18
|
+
|
19
|
+
register(script)
|
20
|
+
end
|
21
|
+
|
22
|
+
def strip_heredoc(string)
|
23
|
+
if string.start_with?('<<')
|
24
|
+
lines = string.split("\n")
|
25
|
+
string = lines[1...-1].join("\n").strip
|
26
|
+
end
|
27
|
+
|
28
|
+
return string
|
29
|
+
end
|
30
|
+
private :strip_heredoc
|
31
|
+
end
|
32
|
+
end
|
data/lib/redstruct.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Dependencies
|
2
|
+
require 'redis'
|
3
|
+
require 'connection_pool'
|
4
|
+
|
5
|
+
# Utility
|
6
|
+
require 'redstruct/version'
|
7
|
+
require 'redstruct/utils/inspectable'
|
8
|
+
require 'redstruct/utils/scriptable'
|
9
|
+
require 'redstruct/utils/coercion'
|
10
|
+
|
11
|
+
# Core
|
12
|
+
require 'redstruct/connection'
|
13
|
+
require 'redstruct/configuration'
|
14
|
+
require 'redstruct/error'
|
15
|
+
require 'redstruct/types/base'
|
16
|
+
|
17
|
+
# Factory
|
18
|
+
require 'redstruct/factory/creation'
|
19
|
+
require 'redstruct/factory/deserialization'
|
20
|
+
require 'redstruct/factory'
|
21
|
+
|
22
|
+
# Base data types
|
23
|
+
require 'redstruct/types/struct'
|
24
|
+
require 'redstruct/types/string'
|
25
|
+
require 'redstruct/types/counter'
|
26
|
+
require 'redstruct/types/hash'
|
27
|
+
require 'redstruct/types/list'
|
28
|
+
require 'redstruct/types/script'
|
29
|
+
require 'redstruct/types/set'
|
30
|
+
require 'redstruct/types/sorted_set'
|
31
|
+
|
32
|
+
module Redstruct
|
33
|
+
class << self
|
34
|
+
def config
|
35
|
+
return @config ||= Configuration.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def factories
|
39
|
+
return @factories ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
def [](key)
|
43
|
+
factory = factories[key]
|
44
|
+
factory = make(name: key) if factory.nil?
|
45
|
+
|
46
|
+
return factory
|
47
|
+
end
|
48
|
+
|
49
|
+
def []=(key, factory)
|
50
|
+
if factory.nil?
|
51
|
+
factories.delete(key)
|
52
|
+
else
|
53
|
+
factories[key] = factory
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def make(name: nil, pool: nil, namespace: nil)
|
58
|
+
factory = Redstruct::Factory.new(pool: pool, namespace: namespace)
|
59
|
+
name = Redstruct if name.nil?
|
60
|
+
self[name] = factory unless name.nil?
|
61
|
+
|
62
|
+
return factory
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redstruct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicolas Pepin-Perreault
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-09 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.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: connection_pool
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.2'
|
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
|
+
description: Provides higher level data structures in Ruby using standard Redis commands.
|
84
|
+
Also provides basic object mapping for pre-existing types.
|
85
|
+
email:
|
86
|
+
- nicolas.pepin-perreault@offerista.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- lib/redstruct.rb
|
94
|
+
- lib/redstruct/configuration.rb
|
95
|
+
- lib/redstruct/connection.rb
|
96
|
+
- lib/redstruct/error.rb
|
97
|
+
- lib/redstruct/factory.rb
|
98
|
+
- lib/redstruct/factory/creation.rb
|
99
|
+
- lib/redstruct/factory/deserialization.rb
|
100
|
+
- lib/redstruct/hls.rb
|
101
|
+
- lib/redstruct/hls/lock.rb
|
102
|
+
- lib/redstruct/hls/queue.rb
|
103
|
+
- lib/redstruct/types/base.rb
|
104
|
+
- lib/redstruct/types/counter.rb
|
105
|
+
- lib/redstruct/types/hash.rb
|
106
|
+
- lib/redstruct/types/list.rb
|
107
|
+
- lib/redstruct/types/script.rb
|
108
|
+
- lib/redstruct/types/set.rb
|
109
|
+
- lib/redstruct/types/sorted_set.rb
|
110
|
+
- lib/redstruct/types/string.rb
|
111
|
+
- lib/redstruct/types/struct.rb
|
112
|
+
- lib/redstruct/utils/coercion.rb
|
113
|
+
- lib/redstruct/utils/inspectable.rb
|
114
|
+
- lib/redstruct/utils/scriptable.rb
|
115
|
+
- lib/redstruct/version.rb
|
116
|
+
- lib/redstruct/yard/defscript_handler.rb
|
117
|
+
- test/redstruct/restruct_test.rb
|
118
|
+
- test/test_helper.rb
|
119
|
+
homepage: https://npepinpe.github.com/redstruct/
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
metadata: {}
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 2.6.6
|
140
|
+
signing_key:
|
141
|
+
specification_version: 4
|
142
|
+
summary: Higher level data structures for Redis.
|
143
|
+
test_files:
|
144
|
+
- test/redstruct/restruct_test.rb
|
145
|
+
- test/test_helper.rb
|