trifle-stats 1.1.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ # Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
2
+ # Initialization code that may require console input (password prompts, [y/n]
3
+ # confirmations, etc.) must go above this block; everything else may go below.
4
+ if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
5
+ source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
6
+ fi
7
+
8
+ source /root/powerlevel10k/powerlevel10k.zsh-theme
9
+
10
+ # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
11
+ [[ ! -f /root/.p10k.zsh ]] || source /root/.p10k.zsh
12
+
13
+ POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true
@@ -1,41 +1,27 @@
1
- FROM ubuntu:20.04
1
+ FROM debian:latest
2
2
 
3
3
  ENV TZ=Europe/Bratislava
4
4
  RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
5
5
 
6
- RUN useradd gitpod -u 33333
7
- RUN mkdir -p /home/gitpod && chown gitpod:gitpod /home/gitpod
8
-
9
6
  # install ubuntu packages
10
7
  RUN apt-get update -q \
11
8
  && apt-get install -y \
12
9
  build-essential \
13
10
  apt-transport-https \
14
- bash \
15
- xterm \
16
- xvfb \
17
- x11vnc \
11
+ zsh \
18
12
  libpq-dev \
19
13
  git \
20
14
  curl \
21
15
  wget \
22
16
  unzip \
23
- dirmngr \
24
17
  gpg \
25
18
  gnupg2 \
26
19
  locales \
27
20
  autoconf \
28
- libncurses5-dev \
29
- libgl1-mesa-dev \
30
- libglu1-mesa-dev \
31
- libpng-dev \
32
- unixodbc-dev \
33
21
  libssl-dev \
34
22
  libreadline-dev \
35
23
  zlib1g-dev \
36
- ffmpeg \
37
24
  tmux \
38
- runit-systemd \
39
25
  htop \
40
26
  vim \
41
27
  && apt-get clean
@@ -46,23 +32,15 @@ ENV LANG en_US.UTF-8
46
32
  ENV LANGUAGE en_US:en
47
33
  ENV LC_ALL en_US.UTF-8
48
34
 
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
35
+ RUN wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true
36
+ RUN git clone --depth=1 https://github.com/romkatv/powerlevel10k.git /root/powerlevel10k
37
+ COPY .zshrc /root/.zshrc
38
+ COPY .p10k.zsh /root/p10k.zsh
61
39
 
62
40
  #install asdf
63
- ENV ASDF_ROOT /home/gitpod/.asdf
41
+ ENV ASDF_ROOT /root/.asdf
64
42
  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
43
+ RUN git clone https://github.com/asdf-vm/asdf.git ${ASDF_ROOT} --branch v0.10.0
66
44
 
67
45
  RUN asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git
68
46
 
@@ -71,7 +49,6 @@ ENV RUBY_VERSION 3.0.0
71
49
  RUN ASDF_RUBY_BUILD_VERSION=v20201225 asdf install ruby ${RUBY_VERSION} \
72
50
  && asdf global ruby ${RUBY_VERSION}
73
51
 
74
- # throw errors if Gemfile has been modified since Gemfile.lock
75
52
  RUN gem install bundler
76
53
 
77
- CMD ["bash"]
54
+ CMD ["zsh"]
data/.gitignore CHANGED
@@ -10,3 +10,5 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
  /.byebug_history
13
+ stats.db
14
+ .DS_Store
data/Gemfile CHANGED
@@ -5,3 +5,7 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
+ gem "mongo", require: false
9
+ gem "pg", require: false
10
+ gem "redis", require: false
11
+ gem "sqlite", require: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- trifle-stats (1.1.2)
4
+ trifle-stats (1.3.1)
5
5
  tzinfo (~> 2.0)
6
6
 
7
7
  GEM
@@ -49,6 +49,8 @@ GEM
49
49
  rubocop-ast (1.4.1)
50
50
  parser (>= 2.7.1.5)
51
51
  ruby-progressbar (1.11.0)
52
+ sqlite (1.0.2)
53
+ sqlite3 (1.4.4)
52
54
  tzinfo (2.0.5)
53
55
  concurrent-ruby (~> 1.0)
54
56
  unicode-display_width (1.7.0)
@@ -61,12 +63,14 @@ DEPENDENCIES
61
63
  bundler (~> 2.1)
62
64
  byebug
63
65
  dotenv
64
- mongo (>= 2.14.0)
65
- pg (>= 1.2)
66
+ mongo
67
+ pg
66
68
  rake (~> 12.0)
67
- redis (>= 4.2)
69
+ redis
68
70
  rspec (~> 3.0)
69
71
  rubocop (= 1.0.0)
72
+ sqlite
73
+ sqlite3 (>= 1.4.4)
70
74
  trifle-stats!
71
75
 
72
76
  BUNDLED WITH
data/README.md CHANGED
@@ -12,7 +12,7 @@ Simple analytics backed by Redis, Postgres, MongoDB, Google Analytics, Segment,
12
12
 
13
13
  ## Documentation
14
14
 
15
- You can find guides and documentation at https://trifle.io/docs/stats
15
+ You can find guides and documentation at https://trifle.io/trifle-stats
16
16
 
17
17
  ## Installation
18
18
 
data/bin/console CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "bundler/setup"
4
4
  require "trifle/stats"
5
+ require "byebug"
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mongo'
4
3
  require_relative '../mixins/packer'
5
4
 
6
5
  module Trifle
@@ -16,6 +15,11 @@ module Trifle
16
15
  @separator = '::'
17
16
  end
18
17
 
18
+ def self.setup!(client, collection_name: 'trifle_stats')
19
+ client[collection_name].create
20
+ client[collection_name].indexes.create_one({ key: 1 }, unique: true)
21
+ end
22
+
19
23
  def inc(keys:, **values)
20
24
  data = self.class.pack(hash: { data: values })
21
25
 
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pg'
4
3
  require_relative '../mixins/packer'
5
4
 
6
5
  module Trifle
@@ -16,58 +15,68 @@ module Trifle
16
15
  @separator = '::'
17
16
  end
18
17
 
19
- def inc(keys:, **values)
20
- keys.map do |key|
21
- pkey = key.join(separator)
18
+ def self.setup!(client = PG::Connection.new, table_name: 'trifle_stats')
19
+ client.exec("CREATE TABLE #{table_name} (key VARCHAR(255) PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}'::jsonb)") # rubocop:disable Layout/LineLength
20
+ end
22
21
 
23
- self.class.pack(hash: values).each do |k, c|
24
- _inc_one(key: pkey, name: k, value: c)
22
+ def inc(keys:, **values)
23
+ data = self.class.pack(hash: values)
24
+ client.transaction do |c|
25
+ keys.map do |key|
26
+ pkey = key.join(separator)
27
+ c.exec(inc_query(key: pkey, data: data))
25
28
  end
26
29
  end
27
30
  end
28
31
 
29
- def _inc_one(key:, name:, value:)
30
- data = { name => value }
31
- query = "INSERT INTO trifle_stats(key, data) VALUES ('#{key}', '#{data.to_json}') ON CONFLICT (key) DO UPDATE SET data = jsonb_set(to_jsonb(trifle_stats.data), '{#{name}}', (COALESCE(trifle_stats.data->>'#{name}','0')::int + #{value})::text::jsonb)" # rubocop:disable Metric/LineLength
32
-
33
- client.exec(query)
32
+ def inc_query(key:, data:)
33
+ <<-SQL
34
+ INSERT INTO #{table_name} (key, data) VALUES ('#{key}', '#{data.to_json}')
35
+ ON CONFLICT (key) DO UPDATE SET data =
36
+ #{data.inject("to_jsonb(#{table_name}.data)") { |o, (k, v)| "jsonb_set(#{o}, '{#{k}}', (COALESCE(trifle_stats.data->>'#{k}', '0')::int + #{v})::text::jsonb)" }};
37
+ SQL
34
38
  end
35
39
 
36
40
  def set(keys:, **values)
37
- keys.map do |key|
38
- pkey = key.join(separator)
39
-
40
- _set_all(key: pkey, **values)
41
+ data = self.class.pack(hash: values)
42
+ client.transaction do |c|
43
+ keys.map do |key|
44
+ pkey = key.join(separator)
45
+ c.exec(set_query(key: pkey, data: data))
46
+ end
41
47
  end
42
48
  end
43
49
 
44
- def _set_all(key:, **values)
45
- data = self.class.pack(hash: values)
46
- query = "INSERT INTO trifle_stats(key, data) VALUES ('#{key}', '#{data.to_json}') ON CONFLICT (key) DO UPDATE SET data = '#{data.to_json}'" # rubocop:disable Metric/LineLength
47
-
48
- client.exec(query)
50
+ def set_query(key:, data:)
51
+ <<-SQL
52
+ INSERT INTO #{table_name} (key, data) VALUES ('#{key}', '#{data.to_json}')
53
+ ON CONFLICT (key) DO UPDATE SET data =
54
+ #{data.inject("to_jsonb(#{table_name}.data)") { |o, (k, v)| "jsonb_set(#{o}, '{#{k}}', (#{v})::text::jsonb)" }}
55
+ SQL
49
56
  end
50
57
 
51
58
  def get(keys:)
52
- keys.map do |key|
53
- pkey = key.join(separator)
59
+ pkeys = keys.map { |key| key.join(separator) }
60
+ data = get_all(keys: pkeys)
61
+ map = data.inject({}) { |o, d| o.merge(d[:key] => d[:data]) }
54
62
 
55
- data = _get(key: pkey)
56
- return {} if data.nil?
63
+ pkeys.map { |pkey| self.class.unpack(hash: map.fetch(pkey, {})) }
64
+ end
65
+
66
+ def get_all(keys:)
67
+ results = client.exec_params(get_query(keys: keys)).to_a
57
68
 
58
- self.class.unpack(hash: data)
69
+ results.map do |r|
70
+ { key: r['key'], data: JSON.parse(r['data']) }
71
+ rescue JSON::ParserError
72
+ { key: r['key'], data: {} }
59
73
  end
60
74
  end
61
75
 
62
- def _get(key:)
63
- result = client.exec_params(
64
- "SELECT * FROM #{table_name} WHERE key = $1 LIMIT 1;", [key]
65
- ).to_a.first
66
- return nil if result.nil?
67
-
68
- JSON.parse(result['data'])
69
- rescue JSON::ParserError
70
- nil
76
+ def get_query(keys:)
77
+ <<-SQL
78
+ SELECT * FROM #{table_name} WHERE key IN ('#{keys.join("', '")}');
79
+ SQL
71
80
  end
72
81
  end
73
82
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'redis'
4
3
  require_relative '../mixins/packer'
5
4
 
6
5
  module Trifle
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../mixins/packer'
4
+
5
+ module Trifle
6
+ module Stats
7
+ module Driver
8
+ class Sqlite
9
+ include Mixins::Packer
10
+ attr_accessor :client, :table_name, :separator
11
+
12
+ def initialize(client = SQLite3::Database.new('stats.db'), table_name: 'trifle_stats')
13
+ @client = client
14
+ @table_name = table_name
15
+ @separator = '::'
16
+ end
17
+
18
+ def self.setup!(client = SQLite3::Database.new('stats.db'), table_name: 'trifle_stats')
19
+ client.execute("CREATE TABLE #{table_name} (key varchar(255), data json);")
20
+ client.execute("CREATE UNIQUE INDEX idx_#{table_name}_key ON #{table_name} (key);")
21
+ end
22
+
23
+ def inc(keys:, **values)
24
+ data = self.class.pack(hash: values)
25
+ client.transaction do |c|
26
+ keys.each do |key|
27
+ pkey = key.join(separator)
28
+ c.execute(inc_query(key: pkey, data: data))
29
+ end
30
+ end
31
+ end
32
+
33
+ def inc_query(key:, data:)
34
+ <<-SQL
35
+ INSERT INTO #{table_name} (key, data) values('#{key}', json('#{data.to_json}'))
36
+ ON CONFLICT (key) DO UPDATE SET data =
37
+ #{data.inject('data') { |o, (k, v)| "json_set(#{o}, '$.#{k}', IFNULL(json_extract(data, '$.#{k}'), 0) + #{v})" }};
38
+ SQL
39
+ end
40
+
41
+ def set(keys:, **values)
42
+ data = self.class.pack(hash: values)
43
+ client.transaction do |c|
44
+ keys.each do |key|
45
+ pkey = key.join(separator)
46
+ c.execute(set_query(key: pkey, data: data))
47
+ end
48
+ end
49
+ end
50
+
51
+ def set_query(key:, data:)
52
+ <<-SQL
53
+ INSERT INTO #{table_name} (key, data) values('#{key}', json('#{data.to_json}'))
54
+ ON CONFLICT (key) DO UPDATE SET data =
55
+ #{data.inject('data') { |o, (k, v)| "json_set(#{o}, '$.#{k}', #{v})" }};
56
+ SQL
57
+ end
58
+
59
+ def get(keys:)
60
+ pkeys = keys.map { |key| key.join(separator) }
61
+ data = get_all(keys: pkeys)
62
+ map = data.inject({}) { |o, d| o.merge(d[:key] => d[:data]) }
63
+
64
+ pkeys.map { |pkey| map.fetch(pkey, {}) }
65
+ end
66
+
67
+ def get_all(keys:)
68
+ results = client.execute(get_query(keys: keys)).to_a
69
+
70
+ results.map do |key, data|
71
+ { key: key, data: JSON.parse(data) }
72
+ rescue JSON::ParserError
73
+ { key: key, data: {} }
74
+ end
75
+ end
76
+
77
+ def get_query(keys:)
78
+ <<-SQL
79
+ SELECT key, data FROM #{table_name} WHERE key IN ('#{keys.join("', '")}');
80
+ SQL
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Trifle
4
4
  module Stats
5
- VERSION = '1.1.2'
5
+ VERSION = '1.3.1'
6
6
  end
7
7
  end
data/lib/trifle/stats.rb CHANGED
@@ -7,6 +7,7 @@ require 'trifle/stats/driver/mongo'
7
7
  require 'trifle/stats/driver/postgres'
8
8
  require 'trifle/stats/driver/process'
9
9
  require 'trifle/stats/driver/redis'
10
+ require 'trifle/stats/driver/sqlite'
10
11
  require 'trifle/stats/mixins/packer'
11
12
  require 'trifle/stats/nocturnal'
12
13
  require 'trifle/stats/configuration'
data/trifle-stats.gemspec CHANGED
@@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency('byebug', '>= 0')
33
33
  spec.add_development_dependency('dotenv')
34
34
  spec.add_development_dependency('mongo', '>= 2.14.0')
35
+ spec.add_development_dependency('sqlite3', '>= 1.4.4')
35
36
  spec.add_development_dependency('pg', '>= 1.2')
36
37
  spec.add_development_dependency('rake', '~> 13.0')
37
38
  spec.add_development_dependency('redis', '>= 4.2')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trifle-stats
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jozef Vaclavik
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-30 00:00:00.000000000 Z
11
+ date: 2022-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 2.14.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 1.4.4
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.4.4
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: pg
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -166,6 +180,8 @@ files:
166
180
  - ".devops/docker/environment/.zshrc"
167
181
  - ".devops/docker/environment/Dockerfile"
168
182
  - ".devops/docker/gitpod/Dockerfile"
183
+ - ".devops/docker/gitpod/base/.p10k.zsh"
184
+ - ".devops/docker/gitpod/base/.zshrc"
169
185
  - ".devops/docker/gitpod/base/Dockerfile"
170
186
  - ".github/workflows/ruby.yml"
171
187
  - ".gitignore"
@@ -191,6 +207,7 @@ files:
191
207
  - lib/trifle/stats/driver/postgres.rb
192
208
  - lib/trifle/stats/driver/process.rb
193
209
  - lib/trifle/stats/driver/redis.rb
210
+ - lib/trifle/stats/driver/sqlite.rb
194
211
  - lib/trifle/stats/mixins/packer.rb
195
212
  - lib/trifle/stats/nocturnal.rb
196
213
  - lib/trifle/stats/operations/timeseries/classify.rb