trifle-ruby 3.0.1 → 3.0.4

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 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