trifle-ruby 3.0.1 → 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50a533193596e6c6aa35b3388449f0b0c1e2962c764a844281d9fe7af71b92ec
4
- data.tar.gz: 30d8947c3e24684eba8fc5560383157f1c71d8efc8bd35c0509a7de63e85ae01
3
+ metadata.gz: 8b971ae3e2273b7b060d1556aa8716015ac92b7c162d8d64e2ce43a9ad18d185
4
+ data.tar.gz: 9ad14a866e880d9885b4b233be51139283baff70b2af9c09ce85ab882e754a92
5
5
  SHA512:
6
- metadata.gz: 0cc1904798efdad76a363c27c4247c829baaa9beaf1fd85b7bb9c636b1adad32f4e851c397a3e015c58b4947e7728a95836c0b32ece1700a87d3edc92e3d2ff1
7
- data.tar.gz: 52f3ee3f90caeb21e96d44ca9e6c81f4c8639b009cdf91de3e6e0ff77cfe4ff17b4d082fc7f58a029cb5684f661e722b1e807a2e36a1918a44cd148166376dd3
6
+ metadata.gz: a5ec3d8760a919408b5e16664c16a49ccb8a8e48a3a194e45e3ea997c0d8048a187bcfc53da7ba973ba9afd0d89e402a20a9cf8d47efd9176bc36111351cfd00
7
+ data.tar.gz: 365cc57ff1247b480decaf732bb0cc7f969c1f7e85e5c3c221598e28ef492d6cfc4483766818f765a595f8254a53fce4611d2d2afd2138f640bf9e3997f03621
@@ -0,0 +1,37 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ main ]
13
+ pull_request:
14
+ branches: [ main ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ matrix:
22
+ ruby-version: ['2.6', '2.7', '3.0']
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
28
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
29
+ # uses: ruby/setup-ruby@v1
30
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
31
+ with:
32
+ ruby-version: ${{ matrix.ruby-version }}
33
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
34
+ - name: Rspec
35
+ run: bundle exec rspec
36
+ - name: Rubocop
37
+ run: bundle exec rubocop
@@ -0,0 +1,18 @@
1
+ image:
2
+ file: .gitpod/Dockerfile
3
+ tasks:
4
+ - init: bundle install
5
+ command: ./bin/console
6
+ - command: redis-server
7
+ github:
8
+ prebuilds:
9
+ # enable for the master/default branch (defaults to true)
10
+ master: true
11
+ # enable for all branches in this repo (defaults to false)
12
+ branches: false
13
+ # enable for pull requests coming from this repo (defaults to true)
14
+ pullRequests: true
15
+ # add a check to pull requests (defaults to true)
16
+ addCheck: true
17
+ # add a "Review in Gitpod" button as a comment to pull requests (defaults to false)
18
+ addComment: false
@@ -0,0 +1 @@
1
+ FROM trifle/gitpod:0.1.0
@@ -0,0 +1,77 @@
1
+ FROM ubuntu:20.04
2
+
3
+ ENV TZ=Europe/Bratislava
4
+ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
5
+
6
+ RUN useradd gitpod -u 33333
7
+ RUN mkdir -p /home/gitpod && chown gitpod:gitpod /home/gitpod
8
+
9
+ # install ubuntu packages
10
+ RUN apt-get update -q \
11
+ && apt-get install -y \
12
+ build-essential \
13
+ apt-transport-https \
14
+ bash \
15
+ xterm \
16
+ xvfb \
17
+ x11vnc \
18
+ libpq-dev \
19
+ git \
20
+ curl \
21
+ wget \
22
+ unzip \
23
+ dirmngr \
24
+ gpg \
25
+ gnupg2 \
26
+ locales \
27
+ autoconf \
28
+ libncurses5-dev \
29
+ libgl1-mesa-dev \
30
+ libglu1-mesa-dev \
31
+ libpng-dev \
32
+ unixodbc-dev \
33
+ libssl-dev \
34
+ libreadline-dev \
35
+ zlib1g-dev \
36
+ ffmpeg \
37
+ tmux \
38
+ runit-systemd \
39
+ htop \
40
+ vim \
41
+ && apt-get clean
42
+
43
+ #set the locale
44
+ RUN locale-gen en_US.UTF-8
45
+ ENV LANG en_US.UTF-8
46
+ ENV LANGUAGE en_US:en
47
+ ENV LC_ALL en_US.UTF-8
48
+
49
+ RUN curl -fsSL https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add -
50
+ RUN echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list
51
+
52
+ RUN apt-get update -q \
53
+ && apt-get install -y \
54
+ postgresql postgresql-contrib \
55
+ # mongodb-org \
56
+ redis-server \
57
+ mariadb-server \
58
+ && apt-get clean
59
+
60
+ USER gitpod
61
+
62
+ #install asdf
63
+ ENV ASDF_ROOT /home/gitpod/.asdf
64
+ ENV PATH "${ASDF_ROOT}/bin:${ASDF_ROOT}/shims:$PATH"
65
+ RUN git clone https://github.com/asdf-vm/asdf.git ${ASDF_ROOT} --branch v0.8.0
66
+
67
+ RUN asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git
68
+
69
+ # install ruby
70
+ ENV RUBY_VERSION 3.0.0
71
+ RUN ASDF_RUBY_BUILD_VERSION=v20201225 asdf install ruby ${RUBY_VERSION} \
72
+ && asdf global ruby ${RUBY_VERSION}
73
+
74
+ # throw errors if Gemfile has been modified since Gemfile.lock
75
+ RUN gem install bundler
76
+
77
+ CMD ["bash"]
@@ -1,5 +1,9 @@
1
+ inherit_mode:
2
+ merge:
3
+ - Exclude
4
+
1
5
  AllCops:
2
- TargetRubyVersion: '3.0.0'
6
+ TargetRubyVersion: '2.6'
3
7
  Exclude:
4
8
  - 'bin/**/*'
5
9
  - 'Rakefile'
@@ -9,6 +13,3 @@ AllCops:
9
13
 
10
14
  Style/Documentation:
11
15
  Enabled: false
12
- #
13
- # Layout/LineLength:
14
- # Max: 80
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- trifle-ruby (3.0.1)
4
+ trifle-ruby (3.0.4)
5
5
  redis (>= 4.2)
6
6
  tzinfo (~> 2.0)
7
7
 
@@ -51,6 +51,7 @@ GEM
51
51
  unicode-display_width (1.7.0)
52
52
 
53
53
  PLATFORMS
54
+ ruby
54
55
  x86_64-darwin-20
55
56
 
56
57
  DEPENDENCIES
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Trifle
2
2
 
3
- Trifle - simple analytics backed by Redis, Postgres, MongoDB, Google Analytics, Segment, or whatever. [^1]
3
+ [![Gem Version](https://badge.fury.io/rb/trifle-ruby.svg)](https://badge.fury.io/rb/trifle-ruby)
4
+ ![Ruby](https://github.com/trifle-io/trifle-ruby/workflows/Ruby/badge.svg?branch=main)
5
+ [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/trifle-io/trifle-ruby)
6
+
7
+ Simple analytics backed by Redis, Postgres, MongoDB, Google Analytics, Segment, or whatever. [^1]
4
8
 
5
9
  Trifle is a _way too_ simple timeline analytics that helps you track custom metrics. Automatically increments counters for each enabled range. It supports timezones and different week beginning.
6
10
 
@@ -35,28 +39,24 @@ Trifle::Ruby.configure do |config|
35
39
  end
36
40
  ```
37
41
 
42
+ ### Track values
43
+
38
44
  Available ranges are `:minute`, `:hour`, `:day`, `:week`, `:month`, `:quarter`, `:year`.
39
45
 
40
46
  Now track your first metrics
41
47
  ```ruby
42
- Trifle::Ruby.track(key: 'event::logs', at: Time.zone.now, values: {count: 1, duration: 2, lines: 241})
48
+ Trifle::Ruby.track(key: 'event::logs', at: Time.now, values: {count: 1, duration: 2, lines: 241})
43
49
  => [{2021-01-25 16:00:00 +0100=>{:count=>1, :duration=>2, :lines=>241}}, {2021-01-25 00:00:00 +0100=>{:count=>1, :duration=>2, :lines=>241}}]
44
50
  # or do it few more times
45
- Trifle::Ruby.track(key: 'event::logs', at: Time.zone.now, values: {count: 1, duration: 1, lines: 56})
51
+ Trifle::Ruby.track(key: 'event::logs', at: Time.now, values: {count: 1, duration: 1, lines: 56})
46
52
  => [{2021-01-25 16:00:00 +0100=>{:count=>1, :duration=>1, :lines=>56}}, {2021-01-25 00:00:00 +0100=>{:count=>1, :duration=>1, :lines=>56}}]
47
- Trifle::Ruby.track(key: 'event::logs', at: Time.zone.now, values: {count: 1, duration: 5, lines: 361})
53
+ Trifle::Ruby.track(key: 'event::logs', at: Time.now, values: {count: 1, duration: 5, lines: 361})
48
54
  => [{2021-01-25 16:00:00 +0100=>{:count=>1, :duration=>5, :lines=>361}}, {2021-01-25 00:00:00 +0100=>{:count=>1, :duration=>5, :lines=>361}}]
49
55
  ```
50
56
 
51
- You can then retrieve your values for specific `range`.
52
- ```ruby
53
- Trifle::Ruby.values_for(key: 'event::logs', from: Time.now.beginning_of_day, to: Time.now.end_of_day, range: :day)
54
- => [{2021-01-25 00:00:00 +0100=>{"count"=>3, "duration"=>8, "lines"=>658}}]
55
- ```
56
-
57
57
  You can also store nested counters like
58
58
  ```ruby
59
- Trifle::Ruby.track(key: 'event::logs', at: Time.zone.now, values: {
59
+ Trifle::Ruby.track(key: 'event::logs', at: Time.now, values: {
60
60
  count: 1,
61
61
  duration: {
62
62
  parsing: 21,
@@ -67,12 +67,63 @@ Trifle::Ruby.track(key: 'event::logs', at: Time.zone.now, values: {
67
67
  })
68
68
  ```
69
69
 
70
+ ### Get values
71
+
72
+ Retrieve your values for specific `range`.
73
+ ```ruby
74
+ Trifle::Ruby.values(key: 'event::logs', from: Time.now, to: Time.now, range: :day)
75
+ => [{2021-01-25 00:00:00 +0100=>{"count"=>3, "duration"=>8, "lines"=>658}}]
76
+ ```
77
+
78
+ ### Configuration
79
+
80
+ Configuration allows you to specify:
81
+ - `driver` - backend driver used to persist and retrieve data.
82
+ - `track_ranges` - list of timeline ranges you would like to track. Value must be list of symbols, defaults to `[:minute, :hour, :day, :week, :month, :quarter, :year]`.
83
+ - `separator` - keys can get serialized in backend, separator is used to join these values. Value must be string, defaults to `::`.
84
+ - `time_zone` - TZInfo zone to properly generate range for timeline values. Value must be valid TZ string identifier, otherwise it defaults and fallbacks to `'GMT'`.
85
+ - `beginning_of_week` - first day of week. Value must be string, defaults to `:monday`.
86
+
87
+ Gem expecs global configuration to be present. You can do this by creating initializer, or calling it on the beginning of your ruby script.
88
+
89
+ Custom configuration can be passed as a keyword argument to `Resource` objects and all module methods (`track`, `values`). This way you can pass different driver or ranges for different type of data youre storing - ie set different ranges or set expiration date on your data.
90
+
91
+ ```ruby
92
+ configuration = Trifle::Ruby::Configuration.new
93
+ configuration.driver = Trifle::Ruby::Driver::Redis.new
94
+ configuration.track_ranges = [:day]
95
+ configuration.time_zone = 'GMT'
96
+ configuration.separator = '#'
97
+
98
+ # or use different driver
99
+ mongo_configuration = Trifle::Ruby::Configuration.new
100
+ mongo_configuration.driver = Trifle::Ruby::Driver::MongoDB.new
101
+ mongo_configuration.time_zone = 'Asia/Dubai'
102
+ ```
103
+
104
+ You can then pass it into module methods.
105
+ ```ruby
106
+ Trifle::Ruby.track(key: 'event#checkout', at: Time.now, values: {count: 1}, config: configuration)
107
+
108
+ Trifle::Ruby.track(key: 'event#checkout', at: Time.now, values: {count: 1}, config: mongo_configuration)
109
+ ```
110
+
111
+ ### Driver
112
+
113
+ Driver is a wrapper around existing client libraries that talk to DB or API. It is used to store and retrieve values. You can read more in [Driver Readme](https://github.com/trifle-io/trifle-ruby/tree/main/lib/trifle/ruby/driver).
114
+
70
115
  ## Development
71
116
 
72
117
  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.
73
118
 
74
119
  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).
75
120
 
121
+ ## Gitpod
122
+
123
+ This repository comes Gitpod ready. If you wanna try and get your hands dirty with Trifle, click [here](https://gitpod.io/#https://github.com/trifle-io/trifle-ruby) and watch magic happening.
124
+
125
+ It launches from custom base image that includes Redis, MongoDB, Postgres & MariaDB. This should give you enough playground to launch `./bin/console` and start messing around. You can see the Gitpod image in the [hub](https://hub.docker.com/r/trifle/gitpod).
126
+
76
127
  ## Contributing
77
128
 
78
129
  Bug reports and pull requests are welcome on GitHub at https://github.com/trifle-io/trifle-ruby.
@@ -3,43 +3,43 @@
3
3
  require 'trifle/ruby/driver/redis'
4
4
  require 'trifle/ruby/mixins/packer'
5
5
  require 'trifle/ruby/nocturnal'
6
- require 'trifle/ruby/client'
7
6
  require 'trifle/ruby/configuration'
8
- require 'trifle/ruby/resource'
7
+ require 'trifle/ruby/operations/timeseries/increment'
8
+ require 'trifle/ruby/operations/timeseries/values'
9
9
  require 'trifle/ruby/version'
10
10
 
11
11
  module Trifle
12
12
  module Ruby
13
13
  class Error < StandardError; end
14
+ class DriverNotFound < Error; end
14
15
 
15
- def self.config
16
- @config ||= Configuration.new
16
+ def self.default
17
+ @default ||= Configuration.new
17
18
  end
18
19
 
19
20
  def self.configure
20
- yield(config)
21
+ yield(default)
21
22
 
22
- config
23
+ default
23
24
  end
24
25
 
25
- def self.client
26
- @client ||= Client.new
26
+ def self.track(key:, at:, values:, config: nil)
27
+ Trifle::Ruby::Operations::Timeseries::Increment.new(
28
+ key: key,
29
+ at: at,
30
+ values: values,
31
+ config: config
32
+ ).perform
27
33
  end
28
34
 
29
- def self.track(key:, at:, values:)
30
- config.ranges.map do |range|
31
- Resource.new(
32
- key: key,
33
- range: range,
34
- at: Nocturnal.new(at).send("beginning_of_#{range}")
35
- ).increment(**values)
36
- end
37
- end
38
-
39
- def self.values_for(key:, from:, to:, range:)
40
- Nocturnal.timeline(from: from, to: to, range: range).map do |at|
41
- Resource.new(key: key, range: range, at: at).values
42
- end
35
+ def self.values(key:, from:, to:, range:, config: nil)
36
+ Trifle::Ruby::Operations::Timeseries::Values.new(
37
+ key: key,
38
+ from: from,
39
+ to: to,
40
+ range: range,
41
+ config: config
42
+ ).perform
43
43
  end
44
44
  end
45
45
  end
@@ -5,19 +5,21 @@ require 'tzinfo'
5
5
  module Trifle
6
6
  module Ruby
7
7
  class Configuration
8
- attr_accessor :driver, :track_ranges, :separator, :time_zone,
8
+ attr_writer :driver
9
+ attr_accessor :track_ranges, :separator, :time_zone,
9
10
  :beginning_of_week
10
11
 
11
12
  def initialize
12
13
  @separator = '::'
13
14
  @ranges = %i[minute hour day week month quarter year]
14
15
  @beginning_of_week = :monday
16
+ @time_zone = 'GMT'
15
17
  end
16
18
 
17
19
  def tz
18
20
  TZInfo::Timezone.get(@time_zone)
19
21
  rescue TZInfo::InvalidTimezoneIdentifier => e
20
- puts "Trifle: #{e} - #{time_zone_name}; Defaulting to GMT."
22
+ puts "Trifle: #{e} - #{time_zone}; Defaulting to GMT."
21
23
 
22
24
  TZInfo::Timezone.get('GMT')
23
25
  end
@@ -28,6 +30,12 @@ module Trifle
28
30
  @ranges & track_ranges
29
31
  end
30
32
 
33
+ def driver
34
+ raise DriverNotFound if @driver.nil?
35
+
36
+ @driver
37
+ end
38
+
31
39
  private
32
40
 
33
41
  def blank?(obj)
@@ -0,0 +1,59 @@
1
+ # Driver
2
+
3
+ Driver is a wrapper class that persists and retrieves values from backend. It needs to implement:
4
+ - `inc(key:, **values)` method to store values
5
+ - `get(key:)` method to retrieve values
6
+
7
+ ## Packer Mixin
8
+
9
+ Some databases cannot store nested hashes/values. Or they cannot perform increment on nested values that does not exist. For this reason you can use Packer mixin that helps you convert values to dot notation.
10
+
11
+ ```ruby
12
+ class Sample
13
+ include Trifle::Ruby::Mixins::Packer
14
+ end
15
+
16
+ values = { a: 1, b: { c: 22, d: 33 } }
17
+ => {:a=>1, :b=>{:c=>22, :d=>33}}
18
+
19
+ packed = Sample.pack(hash: values)
20
+ => {"a"=>1, "b.c"=>22, "b.d"=>33}
21
+
22
+ Sample.unpack(hash: packed)
23
+ => {"a"=>1, "b"=>{"c"=>22, "d"=>33}}
24
+ ```
25
+
26
+ ## Dummy driver
27
+
28
+ Sample of using custom driver that does, well, nothing useful.
29
+
30
+ ```ruby
31
+ irb(main):001:1* class Dummy
32
+ irb(main):002:2* def inc(key:, **values)
33
+ irb(main):003:2* puts "Dumping #{key} => #{values}"
34
+ irb(main):004:1* end
35
+ irb(main):005:2* def get(key:)
36
+ irb(main):006:2* puts "Random for #{key}"
37
+ irb(main):007:2* { count: rand(1000) }
38
+ irb(main):008:1* end
39
+ irb(main):009:0> end
40
+ => :get
41
+
42
+ irb(main):010:0> c = Trifle::Ruby::Configuration.new
43
+ => #<Trifle::Ruby::Configuration:0x00007fe179aed848 @separator="::", @ranges=[:minute, :hour, :day, :week, :month, :quarter, :year], @beginning_of_week=:monday, @time_zone="GMT">
44
+
45
+ irb(main):011:0> c.driver = Dummy.new
46
+ => #<Dummy:0x00007fe176302ac8>
47
+
48
+ irb(main):012:0> c.track_ranges = [:minute, :hour]
49
+ => [:minute, :hour]
50
+
51
+ irb(main):013:0> Trifle::Ruby.track(key: 'sample', at: Time.now, values: {count: 1}, config: c)
52
+ Dumping sample::minute::1611696240 => {:count=>1}
53
+ Dumping sample::hour::1611694800 => {:count=>1}
54
+ => [{2021-01-26 21:24:00 +0000=>{:count=>1}}, {2021-01-26 21:00:00 +0000=>{:count=>1}}]
55
+
56
+ irb(main):014:0> Trifle::Ruby.values(key: 'sample', from: Time.now, to: Time.now, range: :hour, config: c)
57
+ Random for sample::hour::1611694800
58
+ => [{2021-01-26 21:00:00 +0000=>{:count=>405}}]
59
+ ```
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'redis'
4
+ require_relative '../mixins/packer'
4
5
 
5
6
  module Trifle
6
7
  module Ruby
7
8
  module Driver
8
9
  class Redis
10
+ include Mixins::Packer
9
11
  attr_accessor :prefix
10
12
 
11
13
  def initialize(client = ::Redis.current, prefix: 'trfl')
@@ -15,14 +17,18 @@ module Trifle
15
17
 
16
18
  def inc(key:, **values)
17
19
  pkey = [@prefix, key].join('::')
18
- values.each do |k, c|
20
+
21
+ self.class.pack(hash: values).each do |k, c|
19
22
  @client.hincrby(pkey, k, c)
20
23
  end
21
24
  end
22
25
 
23
26
  def get(key:)
24
27
  pkey = [@prefix, key].join('::')
25
- @client.hgetall(pkey)
28
+
29
+ self.class.unpack(
30
+ hash: @client.hgetall(pkey)
31
+ )
26
32
  end
27
33
  end
28
34
  end
@@ -2,25 +2,31 @@
2
2
 
3
3
  module Trifle
4
4
  module Ruby
5
- class Nocturnal
5
+ class Nocturnal # rubocop:disable Metrics/ClassLength
6
6
  DAYS_INTO_WEEK = {
7
7
  sunday: 0, monday: 1, tuesday: 2, wednesday: 3,
8
8
  thursday: 4, friday: 5, saturday: 6
9
9
  }.freeze
10
10
 
11
- def self.timeline(from:, to:, range:)
11
+ def self.timeline(from:, to:, range:, config: nil)
12
12
  list = []
13
- item = new(from).send("beginning_of_#{range}")
14
- while item < to
13
+ from = new(from, config: config).send(range)
14
+ to = new(to, config: config).send(range)
15
+ item = from.dup
16
+ while item <= to
15
17
  list << item
16
- item = Nocturnal.new(list.last).send("next_#{range}")
18
+ item = Nocturnal.new(item, config: config).send("next_#{range}")
17
19
  end
18
20
  list
19
21
  end
20
22
 
21
- def initialize(at)
23
+ def initialize(at, config: nil)
22
24
  @at = at
23
- @tz = Trifle::Ruby.config.tz
25
+ @config = config
26
+ end
27
+
28
+ def config
29
+ @config || Trifle::Ruby.default
24
30
  end
25
31
 
26
32
  def change(**fractions)
@@ -31,71 +37,76 @@ module Trifle
31
37
  fractions.fetch(:hour, @at.hour),
32
38
  fractions.fetch(:minute, @at.min),
33
39
  0, # second
34
- @tz.utc_offset
40
+ config.tz.utc_offset
35
41
  )
36
42
  end
37
43
 
38
- def beginning_of_minute
44
+ def minute
39
45
  change
40
46
  end
41
47
 
42
48
  def next_minute
43
49
  Nocturnal.new(
44
- beginning_of_minute + 60
45
- ).beginning_of_minute
50
+ minute + 60,
51
+ config: config
52
+ ).minute
46
53
  end
47
54
 
48
- def beginning_of_hour
55
+ def hour
49
56
  change(minute: 0)
50
57
  end
51
58
 
52
59
  def next_hour
53
60
  Nocturnal.new(
54
- beginning_of_hour + 60 * 60
55
- ).beginning_of_hour
61
+ hour + 60 * 60,
62
+ config: config
63
+ ).hour
56
64
  end
57
65
 
58
- def beginning_of_day
66
+ def day
59
67
  change(hour: 0, minute: 0)
60
68
  end
61
69
 
62
70
  def next_day
63
71
  Nocturnal.new(
64
- beginning_of_day + 60 * 60 * 24
65
- ).beginning_of_day
72
+ day + 60 * 60 * 24,
73
+ config: config
74
+ ).day
66
75
  end
67
76
 
68
- def beginning_of_week
69
- today = beginning_of_day
77
+ def week
78
+ today = day
70
79
 
71
80
  (today.to_date - days_to_week_start).to_time
72
81
  end
73
82
 
74
83
  def next_week
75
84
  Nocturnal.new(
76
- beginning_of_week + 60 * 60 * 24 * 7
77
- ).beginning_of_week
85
+ week + 60 * 60 * 24 * 7,
86
+ config: config
87
+ ).week
78
88
  end
79
89
 
80
90
  def days_to_week_start
81
91
  start_day_number = DAYS_INTO_WEEK.fetch(
82
- Trifle::Ruby.config.beginning_of_week
92
+ config.beginning_of_week
83
93
  )
84
94
 
85
95
  (@at.wday - start_day_number) % 7
86
96
  end
87
97
 
88
- def beginning_of_month
98
+ def month
89
99
  change(day: 1, hour: 0, minute: 0)
90
100
  end
91
101
 
92
102
  def next_month
93
103
  Nocturnal.new(
94
- beginning_of_month + 60 * 60 * 24 * 31
95
- ).beginning_of_month
104
+ month + 60 * 60 * 24 * 31,
105
+ config: config
106
+ ).month
96
107
  end
97
108
 
98
- def beginning_of_quarter
109
+ def quarter
99
110
  first_quarter_month = @at.month - (2 + @at.month) % 3
100
111
 
101
112
  change(
@@ -108,18 +119,20 @@ module Trifle
108
119
 
109
120
  def next_quarter
110
121
  Nocturnal.new(
111
- beginning_of_quarter + 60 * 60 * 24 * 31 * 3
112
- ).beginning_of_quarter
122
+ quarter + 60 * 60 * 24 * 31 * 3,
123
+ config: config
124
+ ).quarter
113
125
  end
114
126
 
115
- def beginning_of_year
127
+ def year
116
128
  change(month: 1, day: 1, hour: 0, minute: 0)
117
129
  end
118
130
 
119
131
  def next_year
120
132
  Nocturnal.new(
121
- beginning_of_year + 60 * 60 * 24 * 31 * 12
122
- ).beginning_of_year
133
+ year + 60 * 60 * 24 * 31 * 12,
134
+ config: config
135
+ ).year
123
136
  end
124
137
  end
125
138
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trifle
4
+ module Ruby
5
+ module Operations
6
+ module Timeseries
7
+ class Increment
8
+ attr_reader :key, :values
9
+
10
+ def initialize(**keywords)
11
+ @key = keywords.fetch(:key)
12
+ @at = keywords.fetch(:at)
13
+ @values = keywords.fetch(:values)
14
+ @config = keywords[:config]
15
+ end
16
+
17
+ def config
18
+ @config || Trifle::Ruby.default
19
+ end
20
+
21
+ def perform
22
+ config.ranges.map do |range|
23
+ at = Nocturnal.new(@at, config: config).send(range)
24
+ config.driver.inc(
25
+ key: [key, range, at.to_i].join(config.separator),
26
+ **values
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Trifle
4
+ module Ruby
5
+ module Operations
6
+ module Timeseries
7
+ class Values
8
+ attr_reader :key, :range
9
+
10
+ def initialize(**keywords)
11
+ @key = keywords.fetch(:key)
12
+ @from = keywords.fetch(:from)
13
+ @to = keywords.fetch(:to)
14
+ @range = keywords.fetch(:range)
15
+ @config = keywords[:config]
16
+ end
17
+
18
+ def config
19
+ @config || Trifle::Ruby.default
20
+ end
21
+
22
+ def timeline
23
+ Nocturnal.timeline(from: @from, to: @to, range: range)
24
+ end
25
+
26
+ def perform
27
+ timeline.map do |at|
28
+ {
29
+ at => config.driver.get(
30
+ key: [key, range, at.to_i].join(config.separator)
31
+ )
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Trifle
4
4
  module Ruby
5
- VERSION = '3.0.1'
5
+ VERSION = '3.0.4'
6
6
  end
7
7
  end
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  'automatically storing them for each range.'\
12
12
  'Supports multiple backend drivers.'
13
13
  spec.homepage = "https://github.com/trifle-io/trifle-ruby"
14
- spec.required_ruby_version = Gem::Requirement.new('>= 3.0')
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.6')
15
15
 
16
16
  spec.metadata['homepage_uri'] = spec.homepage
17
17
  spec.metadata['source_code_uri'] = "https://github.com/trifle-io/trifle-ruby"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trifle-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jozef Vaclavik
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-25 00:00:00.000000000 Z
11
+ date: 2021-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -130,7 +130,11 @@ executables: []
130
130
  extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
+ - ".github/workflows/ruby.yml"
133
134
  - ".gitignore"
135
+ - ".gitpod.yml"
136
+ - ".gitpod/Dockerfile"
137
+ - ".gitpod/Dockerfile-base"
134
138
  - ".rspec"
135
139
  - ".rubocop.yml"
136
140
  - ".ruby-version"
@@ -144,12 +148,13 @@ files:
144
148
  - bin/console
145
149
  - bin/setup
146
150
  - lib/trifle/ruby.rb
147
- - lib/trifle/ruby/client.rb
148
151
  - lib/trifle/ruby/configuration.rb
152
+ - lib/trifle/ruby/driver/README.md
149
153
  - lib/trifle/ruby/driver/redis.rb
150
154
  - lib/trifle/ruby/mixins/packer.rb
151
155
  - lib/trifle/ruby/nocturnal.rb
152
- - lib/trifle/ruby/resource.rb
156
+ - lib/trifle/ruby/operations/timeseries/increment.rb
157
+ - lib/trifle/ruby/operations/timeseries/values.rb
153
158
  - lib/trifle/ruby/version.rb
154
159
  - trifle-ruby.gemspec
155
160
  homepage: https://github.com/trifle-io/trifle-ruby
@@ -165,7 +170,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
170
  requirements:
166
171
  - - ">="
167
172
  - !ruby/object:Gem::Version
168
- version: '3.0'
173
+ version: '2.6'
169
174
  required_rubygems_version: !ruby/object:Gem::Requirement
170
175
  requirements:
171
176
  - - ">="
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Trifle
4
- module Ruby
5
- class Client
6
- def get(key:)
7
- driver.get(key: key)
8
- end
9
-
10
- def inc(key:, **values)
11
- driver.inc(key: key, **values)
12
- end
13
-
14
- private
15
-
16
- def driver
17
- @driver ||= Trifle::Ruby.config.driver
18
- end
19
- end
20
- end
21
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Trifle
4
- module Ruby
5
- class Resource
6
- include Mixins::Packer
7
- attr_accessor :key, :range, :at
8
-
9
- def initialize(key:, range:, at:)
10
- @key = key
11
- @range = range
12
- @at = at
13
- end
14
-
15
- def full_key
16
- [key, range, at.to_i].join(Trifle::Ruby.config.separator)
17
- end
18
-
19
- def increment(**values)
20
- packed = self.class.pack(hash: values)
21
- Trifle::Ruby.client.inc(key: full_key, **packed)
22
- {
23
- at => values
24
- }
25
- end
26
-
27
- def values
28
- {
29
- at => self.class.unpack(
30
- hash: Trifle::Ruby.client.get(key: full_key)
31
- )
32
- }
33
- end
34
- end
35
- end
36
- end