redis-time-series 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e2bb0c44197c39258529e093bb34aa0a04576743c4f3d07016f607f9d84cd15e
4
+ data.tar.gz: 95ce400fcbbdeff4adcd326dd3927f535410be3180526c34068926c1908ac447
5
+ SHA512:
6
+ metadata.gz: ea5a10679174714e5f7ad63fe00f093c0d65c2c5954d11c19ea5a6b52a1660d897cb63e8ba6f6c037ca7f31e5281857f90a9fe2485dc0b401d37f281bd82ec70
7
+ data.tar.gz: c3cfb8e9632e9876b7cb39888fe89aab86e8becda9b64f3c6c2f4f78e4c58f59595255111820e89914c46a1a29d0a25c8c50f80c6b4311bb60e5b5141137c400
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
File without changes
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,58 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ redis-time-series (0.1.0)
5
+ redis (~> 4.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (6.0.3.1)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 0.7, < 2)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ zeitwerk (~> 2.2, >= 2.2.2)
16
+ coderay (1.1.3)
17
+ concurrent-ruby (1.1.6)
18
+ diff-lcs (1.3)
19
+ i18n (1.8.3)
20
+ concurrent-ruby (~> 1.0)
21
+ method_source (1.0.0)
22
+ minitest (5.14.1)
23
+ pry (0.13.1)
24
+ coderay (~> 1.1)
25
+ method_source (~> 1.0)
26
+ rake (13.0.1)
27
+ redis (4.1.4)
28
+ rspec (3.9.0)
29
+ rspec-core (~> 3.9.0)
30
+ rspec-expectations (~> 3.9.0)
31
+ rspec-mocks (~> 3.9.0)
32
+ rspec-core (3.9.2)
33
+ rspec-support (~> 3.9.3)
34
+ rspec-expectations (3.9.2)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.9.0)
37
+ rspec-mocks (3.9.1)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.9.0)
40
+ rspec-support (3.9.3)
41
+ thread_safe (0.3.6)
42
+ tzinfo (1.2.7)
43
+ thread_safe (~> 0.1)
44
+ zeitwerk (2.3.0)
45
+
46
+ PLATFORMS
47
+ ruby
48
+
49
+ DEPENDENCIES
50
+ activesupport (~> 6.0)
51
+ bundler (~> 1.17)
52
+ pry (~> 0.13)
53
+ rake (~> 13.0)
54
+ redis-time-series!
55
+ rspec (~> 3.0)
56
+
57
+ BUNDLED WITH
58
+ 1.17.2
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Matt Duszynski
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.
@@ -0,0 +1,151 @@
1
+ # RedisTimeSeries
2
+
3
+ A Ruby adapter for the [RedisTimeSeries module](https://oss.redislabs.com/redistimeseries).
4
+
5
+ This doesn't work with vanilla Redis, you need the time series module compiled and installed. Try it with Docker, and see the [module setup guide](https://oss.redislabs.com/redistimeseries/#setup) for additional options.
6
+ ```
7
+ docker run -p 6379:6379 -it --rm redislabs/redistimeseries
8
+ ```
9
+
10
+
11
+ **TL;DR**
12
+ ```ruby
13
+ ts = Redis::TimeSeries.new('foo')
14
+ ts.add 1234
15
+ => #<Redis::TimeSeries::Sample:0x00007f8c0d2561d8 @time=2020-06-25 23:23:04 -0700, @value=0.1234e4>
16
+ ts.add 56
17
+ => #<Redis::TimeSeries::Sample:0x00007f8c0d26c460 @time=2020-06-25 23:23:16 -0700, @value=0.56e2>
18
+ ts.add 78
19
+ => #<Redis::TimeSeries::Sample:0x00007f8c0d276618 @time=2020-06-25 23:23:20 -0700, @value=0.78e2>
20
+ ts.range (Time.now.to_i - 100)..Time.now.to_i
21
+ => [#<Redis::TimeSeries::Sample:0x00007f8c0d297200 @time=2020-06-25 23:23:04 -0700, @value=0.1234e4>,
22
+ #<Redis::TimeSeries::Sample:0x00007f8c0d297048 @time=2020-06-25 23:23:16 -0700, @value=0.56e2>,
23
+ #<Redis::TimeSeries::Sample:0x00007f8c0d296e90 @time=2020-06-25 23:23:20 -0700, @value=0.78e2>]
24
+ ```
25
+
26
+ ## Installation
27
+
28
+ Add this line to your application's Gemfile:
29
+
30
+ ```ruby
31
+ gem 'redis-time-series'
32
+ ```
33
+
34
+ And then execute:
35
+
36
+ $ bundle
37
+
38
+ Or install it yourself as:
39
+
40
+ $ gem install redis-time-series
41
+
42
+ ## Usage
43
+
44
+ Check out the Redis Time Series [command documentation](https://oss.redislabs.com/redistimeseries/master/commands/) first. Should be able to do most of that.
45
+
46
+ ### Creating a Series
47
+ Create a series (issues `TS.CREATE` command) and return a Redis::TimeSeries object for further use. Key param is required, all other arguments are optional.
48
+ ```ruby
49
+ ts = Redis::TimeSeries.create(
50
+ 'your_ts_key',
51
+ labels: ['foo', 'bar'],
52
+ retention: 600,
53
+ uncompressed: false,
54
+ redis: Redis.new(url: ENV['REDIS_URL']) # defaults to Redis.current
55
+ )
56
+ ```
57
+ You can also call `.new` instead of `.create` to skip the `TS.CREATE` command.
58
+ ```ruby
59
+ ts = Redis::TimeSeries.new('your_ts_key')
60
+ ```
61
+
62
+ ### Adding Data to a Series
63
+ Add a single value
64
+ ```ruby
65
+ ts.add 1234
66
+ => #<Redis::TimeSeries::Sample:0x00007f8c0ea7edc8 @time=2020-06-25 23:41:29 -0700, @value=0.1234e4>
67
+ ```
68
+ Add a single value with a timestamp
69
+ ```ruby
70
+ ts.add 1234, 3.minutes.ago # Used ActiveSupport here, but any Time object works fine
71
+ => #<Redis::TimeSeries::Sample:0x00007fa6ce05f3f8 @time=2020-06-25 23:39:54 -0700, @value=0.1234e4>
72
+ ```
73
+ Add multiple values with timestamps
74
+ ```ruby
75
+ ts.madd(2.minutes.ago => 12, 1.minute.ago => 34, Time.now => 56)
76
+ => [1593153909466, 1593153969466, 1593154029466]
77
+ ```
78
+ Increment or decrement the most recent value
79
+ ```ruby
80
+ ts.incrby 2
81
+ => 1593154222877
82
+ ts.decrby 1
83
+ => 1593154251392
84
+ ts.increment # alias of incrby
85
+ => 1593154255069
86
+ ts.decrement # alias of decrby
87
+ => 1593154257344
88
+ ```
89
+ ```ruby
90
+ ts.get
91
+ => #<Redis::TimeSeries::Sample:0x00007fa25f17ed88 @time=2020-06-25 23:50:57 -0700, @value=0.57e2>
92
+ ts.increment
93
+ => 1593154290736
94
+ ts.get
95
+ => #<Redis::TimeSeries::Sample:0x00007fa25f199480 @time=2020-06-25 23:51:30 -0700, @value=0.58e2>
96
+ ```
97
+ Add values to multiple series
98
+ ```ruby
99
+ # Without timestamp (series named "foo" and "bar")
100
+ Redis::TimeSeries.madd(foo: 1234, bar: 5678)
101
+ => [#<Redis::TimeSeries::Sample:0x00007ffb3aa32ae0 @time=2020-06-26 00:09:15 -0700, @value=0.1234e4>,
102
+ #<Redis::TimeSeries::Sample:0x00007ffb3aa326d0 @time=2020-06-26 00:09:15 -0700, @value=0.5678e4>]
103
+ ```
104
+ ```ruby
105
+ # With a timestamp
106
+ Redis::TimeSeries.madd(foo: { 1.minute.ago => 1234 }, bar: { 1.minute.ago => 2345 })
107
+ => [#<Redis::TimeSeries::Sample:0x00007fb102431f88 @time=2020-06-26 00:10:22 -0700, @value=0.1234e4>,
108
+ #<Redis::TimeSeries::Sample:0x00007fb102431d80 @time=2020-06-26 00:10:22 -0700, @value=0.2345e4>]
109
+ ```
110
+
111
+ ### Querying a Series
112
+ Get the most recent value
113
+ ```ruby
114
+ ts.get
115
+ => #<Redis::TimeSeries::Sample:0x00007fa25f1b78b8 @time=2020-06-25 23:51:30 -0700, @value=0.58e2>
116
+ ```
117
+ Get a range of values
118
+ ```ruby
119
+ ts.range 10.minutes.ago..Time.current # Time range as an argument
120
+ => [#<Redis::TimeSeries::Sample:0x00007fa25f13fc28 @time=2020-06-25 23:50:51 -0700, @value=0.57e2>,
121
+ #<Redis::TimeSeries::Sample:0x00007fa25f13db58 @time=2020-06-25 23:50:55 -0700, @value=0.58e2>,
122
+ #<Redis::TimeSeries::Sample:0x00007fa25f13d900 @time=2020-06-25 23:50:57 -0700, @value=0.57e2>,
123
+ #<Redis::TimeSeries::Sample:0x00007fa25f13d680 @time=2020-06-25 23:51:30 -0700, @value=0.58e2>]
124
+ ts.range from: 10.minutes.ago, to: Time.current # Time range as keyword args
125
+ => [#<Redis::TimeSeries::Sample:0x00007fa25dc01f00 @time=2020-06-25 23:50:51 -0700, @value=0.57e2>,
126
+ #<Redis::TimeSeries::Sample:0x00007fa25dc01d20 @time=2020-06-25 23:50:55 -0700, @value=0.58e2>,
127
+ #<Redis::TimeSeries::Sample:0x00007fa25dc01b68 @time=2020-06-25 23:50:57 -0700, @value=0.57e2>,
128
+ #<Redis::TimeSeries::Sample:0x00007fa25dc019b0 @time=2020-06-25 23:51:30 -0700, @value=0.58e2>]
129
+ ```
130
+
131
+ ### TODO
132
+ * `TS.REVRANGE`
133
+ * `TS.MRANGE`/`TS.MREVRANGE`
134
+ * `TS.QUERYINDEX`
135
+ * Compaction rules
136
+ * Filters
137
+ * Probably a bunch more stuff
138
+
139
+ ## Development
140
+
141
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
142
+
143
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
144
+
145
+ ## Contributing
146
+
147
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dzunk/redis-time-series.
148
+
149
+ ## License
150
+
151
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'active_support/core_ext/numeric/time'
5
+ require 'pry'
6
+ require 'redis-time-series'
7
+
8
+ Redis.current.flushall
9
+
10
+ @ts1 = Redis::TimeSeries.create('foo')
11
+ @ts2 = Redis::TimeSeries.create('bar')
12
+ @ts3 = Redis::TimeSeries.create('baz')
13
+
14
+ @series = [@ts1, @ts2, @ts3]
15
+ @series.each do |ts|
16
+ 3.times { ts.increment }
17
+ end
18
+
19
+ Pry.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,9 @@
1
+ require 'bigdecimal'
2
+ require 'time/msec'
3
+ require 'redis'
4
+ require 'redis/time_series'
5
+ require 'redis/time_series/sample'
6
+
7
+ class RedisTimeSeries
8
+ VERSION = '0.1.0'
9
+ end
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+ class Redis
3
+ class TimeSeries
4
+ class << self
5
+ def create(key, **options)
6
+ new(key, **options).create
7
+ end
8
+
9
+ def madd(data)
10
+ data.reduce([]) do |memo, (key, value)|
11
+ if value.is_a?(Hash) || (value.is_a?(Array) && value.first.is_a?(Array))
12
+ # multiple timestamp => value pairs
13
+ value.each do |timestamp, nested_value|
14
+ timestamp = timestamp.ts_msec if timestamp.is_a? Time
15
+ memo << [key, timestamp, nested_value]
16
+ end
17
+ elsif value.is_a? Array
18
+ # single [timestamp, value]
19
+ key = key.ts_msec if key.is_a? Time
20
+ memo << [key, value]
21
+ else
22
+ # single value, no timestamp
23
+ memo << [key, '*', value]
24
+ end
25
+ memo
26
+ end.then do |args|
27
+ puts "DEBUG: TS.MADD #{args.join(' ')}" if ENV['DEBUG']
28
+ redis.call('TS.MADD', args.flatten).each_with_index.map do |result, idx|
29
+ result.is_a?(Redis::CommandError) ? result : Sample.new(result, args[idx][2])
30
+ end
31
+ end
32
+ end
33
+
34
+ def redis
35
+ @redis ||= Redis.current
36
+ end
37
+
38
+ def redis=(client)
39
+ @redis = redis
40
+ end
41
+ end
42
+
43
+ attr_reader :key, :labels, :redis, :retention, :uncompressed
44
+
45
+ def initialize(key, options = {})
46
+ @key = key
47
+ # TODO: read labels from redis if not loaded in memory
48
+ @labels = options[:labels] || []
49
+ @redis = options[:redis] || self.class.redis
50
+ @retention = options[:retention]
51
+ @uncompressed = options[:uncompressed] || false
52
+ end
53
+
54
+ def add(value, timestamp = '*')
55
+ timestamp = timestamp.ts_msec if timestamp.is_a? Time
56
+ ts = cmd 'TS.ADD', key, timestamp, value
57
+ Sample.new(ts, value)
58
+ end
59
+
60
+ def create
61
+ args = [key]
62
+ args << "RETENTION #{retention}" if retention
63
+ args << "UNCOMPRESSED" if uncompressed
64
+ args << "LABELS #{label_string}" if labels.any?
65
+ cmd 'TS.CREATE', args
66
+ self
67
+ end
68
+
69
+ def decrby(value = 1, timestamp = nil)
70
+ args = [key, value]
71
+ args << timestamp if timestamp
72
+ cmd 'TS.DECRBY', args
73
+ end
74
+ alias decrement decrby
75
+
76
+ def destroy
77
+ redis.del key
78
+ end
79
+
80
+ def get
81
+ cmd('TS.GET', key).then do |timestamp, value|
82
+ return unless value
83
+ Sample.new(timestamp, value)
84
+ end
85
+ end
86
+
87
+ def incrby(value = 1, timestamp = nil)
88
+ args = [key, value]
89
+ args << timestamp if timestamp
90
+ cmd 'TS.INCRBY', args
91
+ end
92
+ alias increment incrby
93
+
94
+ # TODO: extract Info module, with methods for each property
95
+ def info
96
+ cmd('TS.INFO', key).each_slice(2).reduce({}) do |h, (key, value)|
97
+ h[key.gsub(/(.)([A-Z])/,'\1_\2').downcase] = value
98
+ h
99
+ end
100
+ end
101
+
102
+ def labels=(val)
103
+ @labels = val
104
+ cmd 'TS.ALTER', key, 'LABELS', label_string
105
+ end
106
+
107
+ def madd(*values)
108
+ if values.one? && values.first.is_a?(Hash)
109
+ # Hash of timestamp => value pairs
110
+ args = values.first.map do |ts, val|
111
+ ts = ts.ts_msec if ts.is_a? Time
112
+ [key, ts, val]
113
+ end.flatten
114
+ elsif values.one? && values.first.is_a?(Array)
115
+ # Array of values, no timestamps
116
+ initial_ts = Time.now.ts_msec
117
+ args = values.first.each_with_index.map do |val, idx|
118
+ [key, initial_ts + idx, val]
119
+ end.flatten
120
+ else
121
+ # Values as individual arguments, no timestamps
122
+ initial_ts = Time.now.ts_msec
123
+ args = values.each_with_index.map do |val, idx|
124
+ [key, initial_ts + idx, val]
125
+ end.flatten
126
+ end
127
+ # TODO: return Sample objects here
128
+ cmd 'TS.MADD', args
129
+ end
130
+
131
+ def range(range, count: nil, agg: nil)
132
+ if range.is_a? Hash
133
+ args = range.fetch(:from), range.fetch(:to)
134
+ elsif range.is_a? Range
135
+ args = range.min, range.max
136
+ end
137
+ args.map! { |ts| (ts.to_f * 1000).to_i }
138
+ args.append('COUNT', count) if count
139
+ args.append('AGGREGATION', agg) if agg
140
+ cmd('TS.RANGE', key, args).map do |ts, val|
141
+ Sample.new(ts, val)
142
+ end
143
+ end
144
+
145
+ def retention=(val)
146
+ @retention = val.to_i
147
+ cmd 'TS.ALTER', key, 'RETENTION', val.to_i
148
+ end
149
+
150
+ private
151
+
152
+ def cmd(name, *args)
153
+ puts "DEBUG: #{name} #{args.join(' ')}" if ENV['DEBUG']
154
+ redis.call name, *args
155
+ end
156
+
157
+ def label_string
158
+ labels.map { |label, value| "#{label} #{value}" }.join(' ')
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ class Redis
3
+ class TimeSeries
4
+ class Sample
5
+ TS_FACTOR = 1000.0
6
+
7
+ attr_reader :time, :value
8
+
9
+ def initialize(timestamp, value)
10
+ @time = Time.at(timestamp / TS_FACTOR)
11
+ @value = BigDecimal(value)
12
+ end
13
+
14
+ def ts_msec
15
+ (time.to_f * TS_FACTOR).to_i
16
+ end
17
+
18
+ def to_h
19
+ {
20
+ timestamp: ts_msec,
21
+ value: value
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ class Time
3
+ # TODO: use refinemenets instead of monkey-patching Time
4
+ def ts_msec
5
+ (to_f * 1000.0).to_i
6
+ end
7
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'redis-time-series'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'redis-time-series'
8
+ spec.version = RedisTimeSeries::VERSION
9
+ spec.authors = ['Matt Duszynski']
10
+ spec.email = ['mattduszynski@gmail.com']
11
+
12
+ spec.summary = %q{A Ruby adapter for the RedisTimeSeries module.}
13
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
14
+ spec.homepage = 'https://github.com/dzunk/redis-time-series'
15
+ spec.license = 'MIT'
16
+
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = spec.homepage
20
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/master/CHANGELOG.md"
21
+ else
22
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
23
+ end
24
+
25
+ # Specify which files should be added to the gem when it is released.
26
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
28
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
+ end
30
+ spec.bindir = 'exe'
31
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ['lib']
33
+
34
+ spec.add_dependency 'redis', '~> 4.0'
35
+
36
+ spec.add_development_dependency 'activesupport', '~> 6.0'
37
+ spec.add_development_dependency 'bundler', '~> 1.17'
38
+ spec.add_development_dependency 'pry', '~> 0.13'
39
+ spec.add_development_dependency 'rake', '~> 13.0'
40
+ spec.add_development_dependency 'rspec', '~> 3.0'
41
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redis-time-series
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Duszynski
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-06-26 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: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '6.0'
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.17'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.17'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.13'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.13'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '13.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '13.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ description:
98
+ email:
99
+ - mattduszynski@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - CHANGELOG.md
107
+ - Gemfile
108
+ - Gemfile.lock
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - bin/console
113
+ - bin/setup
114
+ - lib/redis-time-series.rb
115
+ - lib/redis/time_series.rb
116
+ - lib/redis/time_series/sample.rb
117
+ - lib/time/msec.rb
118
+ - redis-time-series.gemspec
119
+ homepage: https://github.com/dzunk/redis-time-series
120
+ licenses:
121
+ - MIT
122
+ metadata:
123
+ homepage_uri: https://github.com/dzunk/redis-time-series
124
+ source_code_uri: https://github.com/dzunk/redis-time-series
125
+ changelog_uri: https://github.com/dzunk/redis-time-series/blob/master/CHANGELOG.md
126
+ post_install_message:
127
+ rdoc_options: []
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubygems_version: 3.0.3
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: A Ruby adapter for the RedisTimeSeries module.
145
+ test_files: []