trifle-stats 1.2.0 → 1.3.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.
- checksums.yaml +4 -4
- data/.devops/docker/codespaces/Dockerfile +1 -1
- data/.gitignore +1 -0
- data/Gemfile.lock +3 -1
- data/lib/trifle/stats/driver/mongo.rb +5 -0
- data/lib/trifle/stats/driver/postgres.rb +41 -28
- data/lib/trifle/stats/driver/sqlite.rb +86 -0
- data/lib/trifle/stats/version.rb +1 -1
- data/lib/trifle/stats.rb +1 -0
- data/trifle-stats.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a496a80a0581a3fb0ab818d86132fd9b1e7377ff271b25e654e91a543c35eb5
|
4
|
+
data.tar.gz: 85eba8c25e377e2d30b17b092a91bf5f5ef13f8eddbe39c5b5d910ef7f092050
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8f68bd3587f76c996ea3707815d2779e74e68a25a4da0cf74fb27ae592ea66d702e654b39accf11eb3bb03e67d62f16033cc4aa949e396d9e19a3f5bc8c87f1
|
7
|
+
data.tar.gz: ae59825f8565c8ac8cd404f43088fccb42f645a9dcf1519e3fe370d46e181062bce7f31420ddd5cfc3539c852a609551bbbacbe4aa1203b1e69a9f826f0f26ba
|
@@ -1 +1 @@
|
|
1
|
-
FROM trifle/environment:1.0.
|
1
|
+
FROM trifle/environment:1.0.4
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
trifle-stats (1.
|
4
|
+
trifle-stats (1.3.0)
|
5
5
|
tzinfo (~> 2.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -49,6 +49,7 @@ GEM
|
|
49
49
|
rubocop-ast (1.4.1)
|
50
50
|
parser (>= 2.7.1.5)
|
51
51
|
ruby-progressbar (1.11.0)
|
52
|
+
sqlite3 (1.4.4)
|
52
53
|
tzinfo (2.0.5)
|
53
54
|
concurrent-ruby (~> 1.0)
|
54
55
|
unicode-display_width (1.7.0)
|
@@ -67,6 +68,7 @@ DEPENDENCIES
|
|
67
68
|
redis (>= 4.2)
|
68
69
|
rspec (~> 3.0)
|
69
70
|
rubocop (= 1.0.0)
|
71
|
+
sqlite3 (>= 1.4.4)
|
70
72
|
trifle-stats!
|
71
73
|
|
72
74
|
BUNDLED WITH
|
@@ -16,6 +16,11 @@ module Trifle
|
|
16
16
|
@separator = '::'
|
17
17
|
end
|
18
18
|
|
19
|
+
def self.setup!(client, collection_name: 'trifle_stats')
|
20
|
+
client[collection_name].create
|
21
|
+
client[collection_name].indexes.create_one({ key: 1 }, unique: true)
|
22
|
+
end
|
23
|
+
|
19
24
|
def inc(keys:, **values)
|
20
25
|
data = self.class.pack(hash: { data: values })
|
21
26
|
|
@@ -16,56 +16,69 @@ module Trifle
|
|
16
16
|
@separator = '::'
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
19
|
+
def self.setup!(client = PG::Connection.new, table_name: 'trifle_stats')
|
20
|
+
client.exec("CREATE TABLE #{table_name} (key VARCHAR(255) PRIMARY KEY, data JSONB NOT NULL DEFAULT '{}'::jsonb)") # rubocop:disable Layout/LineLength
|
21
|
+
end
|
22
22
|
|
23
|
-
|
23
|
+
def inc(keys:, **values)
|
24
|
+
data = self.class.pack(hash: values)
|
25
|
+
client.transaction do |c|
|
26
|
+
keys.map do |key|
|
27
|
+
pkey = key.join(separator)
|
28
|
+
c.exec(inc_query(key: pkey, data: data))
|
29
|
+
end
|
24
30
|
end
|
25
31
|
end
|
26
32
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
33
|
+
def inc_query(key:, data:)
|
34
|
+
<<-SQL
|
35
|
+
INSERT INTO #{table_name} (key, data) VALUES ('#{key}', '#{data.to_json}')
|
36
|
+
ON CONFLICT (key) DO UPDATE SET data =
|
37
|
+
#{data.inject("to_jsonb(#{table_name}.data)") { |o, (k, v)| "jsonb_set(#{o}, '{#{k}}', (COALESCE(trifle_stats.data->>'#{k}', '0')::int + #{v})::text::jsonb)" }};
|
38
|
+
SQL
|
32
39
|
end
|
33
40
|
|
34
41
|
def set(keys:, **values)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
42
|
+
data = self.class.pack(hash: values)
|
43
|
+
client.transaction do |c|
|
44
|
+
keys.map do |key|
|
45
|
+
pkey = key.join(separator)
|
46
|
+
c.exec(set_query(key: pkey, data: data))
|
47
|
+
end
|
39
48
|
end
|
40
49
|
end
|
41
50
|
|
42
|
-
def
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
51
|
+
def set_query(key:, data:)
|
52
|
+
<<-SQL
|
53
|
+
INSERT INTO #{table_name} (key, data) VALUES ('#{key}', '#{data.to_json}')
|
54
|
+
ON CONFLICT (key) DO UPDATE SET data =
|
55
|
+
#{data.inject("to_jsonb(#{table_name}.data)") { |o, (k, v)| "jsonb_set(#{o}, '{#{k}}', (#{v})::text::jsonb)" }}
|
56
|
+
SQL
|
47
57
|
end
|
48
58
|
|
49
59
|
def get(keys:)
|
50
60
|
pkeys = keys.map { |key| key.join(separator) }
|
51
|
-
data =
|
52
|
-
map = data.inject({}) { |o, d| o.merge(d[
|
61
|
+
data = get_all(keys: pkeys)
|
62
|
+
map = data.inject({}) { |o, d| o.merge(d[:key] => d[:data]) }
|
53
63
|
|
54
|
-
pkeys.map { |pkey| self.class.unpack(hash: map
|
64
|
+
pkeys.map { |pkey| self.class.unpack(hash: map.fetch(pkey, {})) }
|
55
65
|
end
|
56
66
|
|
57
|
-
def
|
58
|
-
results = client.exec_params(
|
59
|
-
"SELECT * FROM #{table_name} WHERE key IN ('#{keys.join("', '")}');"
|
60
|
-
).to_a
|
67
|
+
def get_all(keys:)
|
68
|
+
results = client.exec_params(get_query(keys: keys)).to_a
|
61
69
|
|
62
70
|
results.map do |r|
|
63
|
-
r['
|
64
|
-
r
|
71
|
+
{ key: r['key'], data: JSON.parse(r['data']) }
|
65
72
|
rescue JSON::ParserError
|
66
|
-
r
|
73
|
+
{ key: r['key'], data: {} }
|
67
74
|
end
|
68
75
|
end
|
76
|
+
|
77
|
+
def get_query(keys:)
|
78
|
+
<<-SQL
|
79
|
+
SELECT * FROM #{table_name} WHERE key IN ('#{keys.join("', '")}');
|
80
|
+
SQL
|
81
|
+
end
|
69
82
|
end
|
70
83
|
end
|
71
84
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sqlite3'
|
4
|
+
require_relative '../mixins/packer'
|
5
|
+
|
6
|
+
module Trifle
|
7
|
+
module Stats
|
8
|
+
module Driver
|
9
|
+
class Sqlite
|
10
|
+
include Mixins::Packer
|
11
|
+
attr_accessor :client, :table_name, :separator
|
12
|
+
|
13
|
+
def initialize(client = SQLite3::Database.new('stats.db'), table_name: 'trifle_stats')
|
14
|
+
@client = client
|
15
|
+
@table_name = table_name
|
16
|
+
@separator = '::'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.setup!(client = SQLite3::Database.new('stats.db'), table_name: 'trifle_stats')
|
20
|
+
client.execute("CREATE TABLE #{table_name} (key varchar(255), data json);")
|
21
|
+
client.execute("CREATE UNIQUE INDEX idx_#{table_name}_key ON #{table_name} (key);")
|
22
|
+
end
|
23
|
+
|
24
|
+
def inc(keys:, **values)
|
25
|
+
data = self.class.pack(hash: values)
|
26
|
+
client.transaction do |c|
|
27
|
+
keys.each do |key|
|
28
|
+
pkey = key.join(separator)
|
29
|
+
c.execute(inc_query(key: pkey, data: data))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def inc_query(key:, data:)
|
35
|
+
<<-SQL
|
36
|
+
INSERT INTO #{table_name} (key, data) values('#{key}', json('#{data.to_json}'))
|
37
|
+
ON CONFLICT (key) DO UPDATE SET data =
|
38
|
+
#{data.inject('data') { |o, (k, v)| "json_set(#{o}, '$.#{k}', IFNULL(json_extract(data, '$.#{k}'), 0) + #{v})" }};
|
39
|
+
SQL
|
40
|
+
end
|
41
|
+
|
42
|
+
def set(keys:, **values)
|
43
|
+
data = self.class.pack(hash: values)
|
44
|
+
client.transaction do |c|
|
45
|
+
keys.each do |key|
|
46
|
+
pkey = key.join(separator)
|
47
|
+
c.execute(set_query(key: pkey, data: data))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_query(key:, data:)
|
53
|
+
<<-SQL
|
54
|
+
INSERT INTO #{table_name} (key, data) values('#{key}', json('#{data.to_json}'))
|
55
|
+
ON CONFLICT (key) DO UPDATE SET data =
|
56
|
+
#{data.inject('data') { |o, (k, v)| "json_set(#{o}, '$.#{k}', #{v})" }};
|
57
|
+
SQL
|
58
|
+
end
|
59
|
+
|
60
|
+
def get(keys:)
|
61
|
+
pkeys = keys.map { |key| key.join(separator) }
|
62
|
+
data = get_all(keys: pkeys)
|
63
|
+
map = data.inject({}) { |o, d| o.merge(d[:key] => d[:data]) }
|
64
|
+
|
65
|
+
pkeys.map { |pkey| map.fetch(pkey, {}) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_all(keys:)
|
69
|
+
results = client.execute(get_query(keys: keys)).to_a
|
70
|
+
|
71
|
+
results.map do |key, data|
|
72
|
+
{ key: key, data: JSON.parse(data) }
|
73
|
+
rescue JSON::ParserError
|
74
|
+
{ key: key, data: {} }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_query(keys:)
|
79
|
+
<<-SQL
|
80
|
+
SELECT key, data FROM #{table_name} WHERE key IN ('#{keys.join("', '")}');
|
81
|
+
SQL
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/trifle/stats/version.rb
CHANGED
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.
|
4
|
+
version: 1.3.0
|
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-
|
11
|
+
date: 2022-08-01 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
|
@@ -191,6 +205,7 @@ files:
|
|
191
205
|
- lib/trifle/stats/driver/postgres.rb
|
192
206
|
- lib/trifle/stats/driver/process.rb
|
193
207
|
- lib/trifle/stats/driver/redis.rb
|
208
|
+
- lib/trifle/stats/driver/sqlite.rb
|
194
209
|
- lib/trifle/stats/mixins/packer.rb
|
195
210
|
- lib/trifle/stats/nocturnal.rb
|
196
211
|
- lib/trifle/stats/operations/timeseries/classify.rb
|