trifle-stats 1.1.2 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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