fbe 0.21.3 → 0.23.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/Gemfile.lock +8 -4
- data/fbe.gemspec +1 -0
- data/lib/fbe/middleware/sqlite_store.rb +16 -10
- data/lib/fbe/octo.rb +6 -4
- data/lib/fbe.rb +1 -1
- data/test/fbe/middleware/test_sqlite_store.rb +18 -20
- data/test/test__helper.rb +4 -0
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7faea911e89cea0abccc6d5f664a1ef5dd1ab8b6853ee0b2b6b97077c604f64d
|
4
|
+
data.tar.gz: 88ddb605cd24f68b965aa8ff2200c75c6759d175d130fded4f66ebb02540b00d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 283110a6a7bd12876e0f383f9d243309b0ff0e9495f0987e1e2dc3a84ce5e76e2aa44e86bafe6bcc992f1ec7eae8f36da7206d8f3b18b57320f9339fb7c781d1
|
7
|
+
data.tar.gz: fd3ce178823ca8e9b830b32143b80babda13d0e5f28549728ecd8d8e7635febc177b8691bd189ef9549d01a2ecf036fc9306697ff31856827ec018268338eb60
|
data/Gemfile.lock
CHANGED
@@ -10,6 +10,7 @@ PATH
|
|
10
10
|
faraday-http-cache (~> 2.5)
|
11
11
|
faraday-multipart (~> 1.1)
|
12
12
|
faraday-retry (~> 2.3)
|
13
|
+
filesize (~> 0.2)
|
13
14
|
graphql-client (~> 0.26)
|
14
15
|
judges (~> 0.46)
|
15
16
|
liquid (~> 5.5)
|
@@ -63,17 +64,19 @@ GEM
|
|
63
64
|
crack (1.0.0)
|
64
65
|
bigdecimal
|
65
66
|
rexml
|
66
|
-
decoor (0.0
|
67
|
+
decoor (0.1.0)
|
67
68
|
docile (1.4.1)
|
68
69
|
drb (2.2.3)
|
69
70
|
elapsed (0.0.1)
|
70
71
|
loog (> 0)
|
71
72
|
tago (> 0)
|
73
|
+
ellipsized (0.3.0)
|
72
74
|
ethon (0.16.0)
|
73
75
|
ffi (>= 1.15.0)
|
74
|
-
factbase (0.11.
|
76
|
+
factbase (0.11.1)
|
75
77
|
backtrace (~> 0.4)
|
76
78
|
decoor (~> 0.0)
|
79
|
+
ellipsized (~> 0.3)
|
77
80
|
json (~> 2.7)
|
78
81
|
logger (~> 1.0)
|
79
82
|
loog (~> 0.6)
|
@@ -98,6 +101,7 @@ GEM
|
|
98
101
|
ffi (1.17.2-x86_64-darwin)
|
99
102
|
ffi (1.17.2-x86_64-linux-gnu)
|
100
103
|
fiber-storage (1.0.1)
|
104
|
+
filesize (0.2.0)
|
101
105
|
gli (2.22.2)
|
102
106
|
ostruct
|
103
107
|
graphql (2.5.9)
|
@@ -112,7 +116,7 @@ GEM
|
|
112
116
|
concurrent-ruby (~> 1.0)
|
113
117
|
iri (0.11.2)
|
114
118
|
json (2.12.2)
|
115
|
-
judges (0.50.
|
119
|
+
judges (0.50.5)
|
116
120
|
backtrace (~> 0.4)
|
117
121
|
baza.rb (~> 0.5)
|
118
122
|
concurrent-ruby (~> 1.2)
|
@@ -180,7 +184,7 @@ GEM
|
|
180
184
|
regexp_parser (2.10.0)
|
181
185
|
retries (0.0.5)
|
182
186
|
rexml (3.4.1)
|
183
|
-
rubocop (1.
|
187
|
+
rubocop (1.77.0)
|
184
188
|
json (~> 2.3)
|
185
189
|
language_server-protocol (~> 3.17.0.2)
|
186
190
|
lint_roller (~> 1.1.0)
|
data/fbe.gemspec
CHANGED
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_dependency 'faraday-http-cache', '~>2.5'
|
31
31
|
s.add_dependency 'faraday-multipart', '~>1.1'
|
32
32
|
s.add_dependency 'faraday-retry', '~>2.3'
|
33
|
+
s.add_dependency 'filesize', '~>0.2'
|
33
34
|
s.add_dependency 'graphql-client', '~>0.26'
|
34
35
|
s.add_dependency 'judges', '~>0.46'
|
35
36
|
s.add_dependency 'liquid', '~>5.5'
|
@@ -3,10 +3,11 @@
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 Zerocracy
|
4
4
|
# SPDX-License-Identifier: MIT
|
5
5
|
|
6
|
-
require '
|
6
|
+
require 'filesize'
|
7
7
|
require 'json'
|
8
|
-
require 'sqlite3'
|
9
8
|
require 'loog'
|
9
|
+
require 'sqlite3'
|
10
|
+
require 'time'
|
10
11
|
require_relative '../../fbe'
|
11
12
|
require_relative '../../fbe/middleware'
|
12
13
|
|
@@ -28,7 +29,7 @@ require_relative '../../fbe/middleware'
|
|
28
29
|
# '/path/to/cache.db',
|
29
30
|
# '1.0.0',
|
30
31
|
# loog: logger,
|
31
|
-
# maxsize:
|
32
|
+
# maxsize: '50Mb'
|
32
33
|
# )
|
33
34
|
#
|
34
35
|
# # Use with Faraday
|
@@ -51,8 +52,9 @@ class Fbe::Middleware::SqliteStore
|
|
51
52
|
# @param version [String] Version identifier for cache compatibility
|
52
53
|
# @param loog [Loog] Logger instance (optional, defaults to Loog::NULL)
|
53
54
|
# @param maxsize [Integer] Maximum database size in bytes (optional, defaults to 10MB)
|
55
|
+
# @param maxvsize [Integer] Maximum size in bytes of a single value (optional, defaults to 10Kb)
|
54
56
|
# @raise [ArgumentError] If path is nil/empty, directory doesn't exist, or version is nil/empty
|
55
|
-
def initialize(path, version, loog: Loog::NULL, maxsize:
|
57
|
+
def initialize(path, version, loog: Loog::NULL, maxsize: '10Mb', maxvsize: '10Kb')
|
56
58
|
raise ArgumentError, 'Database path cannot be nil or empty' if path.nil? || path.empty?
|
57
59
|
dir = File.dirname(path)
|
58
60
|
raise ArgumentError, "Directory #{dir} does not exist" unless File.directory?(dir)
|
@@ -60,7 +62,8 @@ class Fbe::Middleware::SqliteStore
|
|
60
62
|
@path = File.absolute_path(path)
|
61
63
|
@version = version
|
62
64
|
@loog = loog
|
63
|
-
@maxsize = maxsize
|
65
|
+
@maxsize = Filesize.from(maxsize.to_s).to_i
|
66
|
+
@maxvsize = Filesize.from(maxvsize.to_s).to_i
|
64
67
|
end
|
65
68
|
|
66
69
|
# Read a value from the cache.
|
@@ -91,10 +94,10 @@ class Fbe::Middleware::SqliteStore
|
|
91
94
|
def write(key, value)
|
92
95
|
return if value.is_a?(Array) && value.any? do |vv|
|
93
96
|
req = JSON.parse(vv[0])
|
94
|
-
req['
|
97
|
+
req['method'] != 'get'
|
95
98
|
end
|
96
99
|
value = JSON.dump(value)
|
97
|
-
return if value.bytesize >
|
100
|
+
return if value.bytesize > @maxvsize
|
98
101
|
perform do |t|
|
99
102
|
t.execute(<<~SQL, [key, value, Time.now.utc.iso8601])
|
100
103
|
INSERT INTO cache(key, value, touched_at) VALUES(?1, ?2, ?3)
|
@@ -159,8 +162,8 @@ class Fbe::Middleware::SqliteStore
|
|
159
162
|
end
|
160
163
|
if File.size(@path) > @maxsize
|
161
164
|
@loog.info(
|
162
|
-
"SQLite cache file size (#{File.size(@path)} bytes) exceeds " \
|
163
|
-
"#{@maxsize
|
165
|
+
"SQLite cache file size (#{Filesize.from(File.size(@path).to_s).pretty} bytes) exceeds " \
|
166
|
+
"#{Filesize.from(@maxsize.to_s).pretty}, cleaning up old entries"
|
164
167
|
)
|
165
168
|
deleted = 0
|
166
169
|
while d.execute(<<~SQL).dig(0, 0) > @maxsize
|
@@ -176,7 +179,10 @@ class Fbe::Middleware::SqliteStore
|
|
176
179
|
end
|
177
180
|
end
|
178
181
|
d.execute 'VACUUM;'
|
179
|
-
@loog.info(
|
182
|
+
@loog.info(
|
183
|
+
"Deleted #{deleted} old cache entries, " \
|
184
|
+
"new file size: #{Filesize.from(File.size(@path).to_s).pretty} bytes"
|
185
|
+
)
|
180
186
|
end
|
181
187
|
at_exit { @db&.close }
|
182
188
|
end
|
data/lib/fbe/octo.rb
CHANGED
@@ -7,6 +7,7 @@ require 'json'
|
|
7
7
|
require 'decoor'
|
8
8
|
require 'faraday/http_cache'
|
9
9
|
require 'faraday/retry'
|
10
|
+
require 'filesize'
|
10
11
|
require 'loog'
|
11
12
|
require 'obk'
|
12
13
|
require 'octokit'
|
@@ -82,12 +83,13 @@ def Fbe.octo(options: $options, global: $global, loog: $loog)
|
|
82
83
|
backoff_factor: 2
|
83
84
|
)
|
84
85
|
if options.sqlite_cache
|
85
|
-
maxsize = options.sqlite_cache_maxsize ||
|
86
|
-
|
86
|
+
maxsize = Filesize.from(options.sqlite_cache_maxsize || '10M').to_i
|
87
|
+
maxvsize = Filesize.from(options.sqlite_cache_maxxsize || '10K').to_i
|
88
|
+
store = Fbe::Middleware::SqliteStore.new(options.sqlite_cache, Fbe::VERSION, loog:, maxsize:, maxvsize:)
|
87
89
|
loog.info(
|
88
90
|
"Using HTTP cache in SQLite file: #{store.path} (" \
|
89
|
-
"#{File.exist?(store.path) ?
|
90
|
-
"max size: #{maxsize
|
91
|
+
"#{File.exist?(store.path) ? Filesize.from(File.size(store.path).to_s).pretty : 'file is absent'}, " \
|
92
|
+
"max size: #{Filesize.from(maxsize.to_s).pretty}, max vsize: #{Filesize.from(maxvsize.to_s).pretty})"
|
91
93
|
)
|
92
94
|
builder.use(
|
93
95
|
Faraday::HttpCache,
|
data/lib/fbe.rb
CHANGED
@@ -33,14 +33,14 @@ class SqliteStoreTest < Fbe::Test
|
|
33
33
|
|
34
34
|
def test_returns_empty_list
|
35
35
|
with_tmpfile('b.db') do |f|
|
36
|
-
store = Fbe::Middleware::SqliteStore.new(f, '0.0.0')
|
36
|
+
store = Fbe::Middleware::SqliteStore.new(f, '0.0.0', loog: fake_loog)
|
37
37
|
assert_empty(store.all)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def test_clear_all_keys
|
42
42
|
with_tmpfile('a.db') do |f|
|
43
|
-
store = Fbe::Middleware::SqliteStore.new(f, '0.0.0')
|
43
|
+
store = Fbe::Middleware::SqliteStore.new(f, '0.0.0', loog: fake_loog)
|
44
44
|
k = 'a key'
|
45
45
|
store.write(k, 'some value')
|
46
46
|
store.clear
|
@@ -50,20 +50,20 @@ class SqliteStoreTest < Fbe::Test
|
|
50
50
|
|
51
51
|
def test_empty_all_if_not_written
|
52
52
|
with_tmpfile do |f|
|
53
|
-
store = Fbe::Middleware::SqliteStore.new(f, '0.0.0')
|
53
|
+
store = Fbe::Middleware::SqliteStore.new(f, '0.0.0', loog: fake_loog)
|
54
54
|
assert_empty(store.all)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
def test_wrong_db_path
|
59
59
|
assert_raises(ArgumentError) do
|
60
|
-
Fbe::Middleware::SqliteStore.new(nil, '0.0.0').read('my_key')
|
60
|
+
Fbe::Middleware::SqliteStore.new(nil, '0.0.0', loog: fake_loog).read('my_key')
|
61
61
|
end
|
62
62
|
assert_raises(ArgumentError) do
|
63
|
-
Fbe::Middleware::SqliteStore.new('', '0.0.0').read('my_key')
|
63
|
+
Fbe::Middleware::SqliteStore.new('', '0.0.0', loog: fake_loog).read('my_key')
|
64
64
|
end
|
65
65
|
assert_raises(ArgumentError) do
|
66
|
-
Fbe::Middleware::SqliteStore.new('/fakepath/fakefolder/test.db', '0.0.0').read('my_key')
|
66
|
+
Fbe::Middleware::SqliteStore.new('/fakepath/fakefolder/test.db', '0.0.0', loog: fake_loog).read('my_key')
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -72,7 +72,7 @@ class SqliteStoreTest < Fbe::Test
|
|
72
72
|
File.binwrite(f, Array.new(20) { rand(0..255) }.pack('C*'))
|
73
73
|
ex =
|
74
74
|
assert_raises(SQLite3::NotADatabaseException) do
|
75
|
-
Fbe::Middleware::SqliteStore.new(f, '0.0.0').read('my_key')
|
75
|
+
Fbe::Middleware::SqliteStore.new(f, '0.0.0', loog: fake_loog).read('my_key')
|
76
76
|
end
|
77
77
|
assert_match('file is not a database', ex.message)
|
78
78
|
end
|
@@ -83,7 +83,6 @@ class SqliteStoreTest < Fbe::Test
|
|
83
83
|
require 'tempfile'
|
84
84
|
require 'sqlite3'
|
85
85
|
require 'fbe/middleware/sqlite_store'
|
86
|
-
|
87
86
|
SQLite3::Database.class_eval do
|
88
87
|
prepend(Module.new do
|
89
88
|
def close
|
@@ -92,7 +91,6 @@ class SqliteStoreTest < Fbe::Test
|
|
92
91
|
end
|
93
92
|
end)
|
94
93
|
end
|
95
|
-
|
96
94
|
Tempfile.open('test.db') do |f|
|
97
95
|
Fbe::Middleware::SqliteStore.new(f.path, '0.0.0').then do |s|
|
98
96
|
s.write('my_key', 'my_value')
|
@@ -111,15 +109,15 @@ class SqliteStoreTest < Fbe::Test
|
|
111
109
|
|
112
110
|
def test_different_versions
|
113
111
|
with_tmpfile('d.db') do |f|
|
114
|
-
Fbe::Middleware::SqliteStore.new(f, '0.0.1').then do |store|
|
112
|
+
Fbe::Middleware::SqliteStore.new(f, '0.0.1', loog: fake_loog).then do |store|
|
115
113
|
store.write('kkk1', 'some value')
|
116
114
|
store.write('kkk2', 'another value')
|
117
115
|
end
|
118
|
-
Fbe::Middleware::SqliteStore.new(f, '0.0.1').then do |store|
|
116
|
+
Fbe::Middleware::SqliteStore.new(f, '0.0.1', loog: fake_loog).then do |store|
|
119
117
|
assert_equal('some value', store.read('kkk1'))
|
120
118
|
assert_equal('another value', store.read('kkk2'))
|
121
119
|
end
|
122
|
-
Fbe::Middleware::SqliteStore.new(f, '0.0.2').then do |store|
|
120
|
+
Fbe::Middleware::SqliteStore.new(f, '0.0.2', loog: fake_loog).then do |store|
|
123
121
|
assert_nil(store.read('kkk1'))
|
124
122
|
assert_nil(store.read('kkk2'))
|
125
123
|
end
|
@@ -129,10 +127,10 @@ class SqliteStoreTest < Fbe::Test
|
|
129
127
|
def test_initialize_wrong_version
|
130
128
|
with_tmpfile('e.db') do |f|
|
131
129
|
msg = 'Version cannot be nil or empty'
|
132
|
-
assert_raises(ArgumentError) { Fbe::Middleware::SqliteStore.new(f, nil) }.then do |ex|
|
130
|
+
assert_raises(ArgumentError) { Fbe::Middleware::SqliteStore.new(f, nil, loog: fake_loog) }.then do |ex|
|
133
131
|
assert_match(msg, ex.message)
|
134
132
|
end
|
135
|
-
assert_raises(ArgumentError) { Fbe::Middleware::SqliteStore.new(f, '') }.then do |ex|
|
133
|
+
assert_raises(ArgumentError) { Fbe::Middleware::SqliteStore.new(f, '', loog: fake_loog) }.then do |ex|
|
136
134
|
assert_match(msg, ex.message)
|
137
135
|
end
|
138
136
|
end
|
@@ -140,11 +138,11 @@ class SqliteStoreTest < Fbe::Test
|
|
140
138
|
|
141
139
|
def test_skip_write_if_value_more_then_10k_bytes
|
142
140
|
with_tmpfile('a.db') do |f|
|
143
|
-
Fbe::Middleware::SqliteStore.new(f, '0.0.1').then do |store|
|
141
|
+
Fbe::Middleware::SqliteStore.new(f, '0.0.1', loog: fake_loog).then do |store|
|
144
142
|
store.write('a', 'a' * 9_997)
|
145
143
|
store.write('b', 'b' * 9_998)
|
146
|
-
store.write('c', 'c' *
|
147
|
-
store.write('d', 'd' *
|
144
|
+
store.write('c', 'c' * 19_999)
|
145
|
+
store.write('d', 'd' * 30_000)
|
148
146
|
assert_equal('a' * 9_997, store.read('a'))
|
149
147
|
assert_equal('b' * 9_998, store.read('b'))
|
150
148
|
assert_nil(store.read('c'))
|
@@ -155,7 +153,7 @@ class SqliteStoreTest < Fbe::Test
|
|
155
153
|
|
156
154
|
def test_shrink_cache_if_more_then_10_mb
|
157
155
|
with_tmpfile('large.db') do |f|
|
158
|
-
Fbe::Middleware::SqliteStore.new(f, '0.0.1').then do |store|
|
156
|
+
Fbe::Middleware::SqliteStore.new(f, '0.0.1', loog: fake_loog).then do |store|
|
159
157
|
key = 'aaa'
|
160
158
|
alpha = ('a'..'z').to_a
|
161
159
|
store.write('a', 'aa')
|
@@ -173,7 +171,7 @@ class SqliteStoreTest < Fbe::Test
|
|
173
171
|
end
|
174
172
|
end
|
175
173
|
assert_operator(File.size(f), :>, 10 * 1024 * 1024)
|
176
|
-
Fbe::Middleware::SqliteStore.new(f, '0.0.1').then do |store|
|
174
|
+
Fbe::Middleware::SqliteStore.new(f, '0.0.1', loog: fake_loog).then do |store|
|
177
175
|
assert_equal('aa', store.read('a'))
|
178
176
|
assert_nil(store.read('b'))
|
179
177
|
assert_equal('cc', store.read('c'))
|
@@ -193,7 +191,7 @@ class SqliteStoreTest < Fbe::Test
|
|
193
191
|
d.execute 'CREATE TABLE IF NOT EXISTS meta(key TEXT UNIQUE NOT NULL, value TEXT);'
|
194
192
|
d.execute "INSERT INTO meta(key, value) VALUES('version', ?);", ['0.0.1']
|
195
193
|
end
|
196
|
-
Fbe::Middleware::SqliteStore.new(f, '0.0.1').then do |store|
|
194
|
+
Fbe::Middleware::SqliteStore.new(f, '0.0.1', loog: fake_loog).then do |store|
|
197
195
|
assert_equal('value1', store.read('key1'))
|
198
196
|
assert_equal('value2', store.read('key2'))
|
199
197
|
rescue SQLite3::SQLException => e
|
data/test/test__helper.rb
CHANGED
@@ -31,6 +31,7 @@ end
|
|
31
31
|
require 'minitest/reporters'
|
32
32
|
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
|
33
33
|
|
34
|
+
require 'loog'
|
34
35
|
require 'minitest/stub_const'
|
35
36
|
require 'minitest/autorun'
|
36
37
|
require 'webmock/minitest'
|
@@ -38,4 +39,7 @@ require_relative '../lib/fbe'
|
|
38
39
|
|
39
40
|
# Parent class for all tests.
|
40
41
|
class Fbe::Test < Minitest::Test
|
42
|
+
def fake_loog
|
43
|
+
Loog::VERBOSE
|
44
|
+
end
|
41
45
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fbe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
@@ -121,6 +121,20 @@ dependencies:
|
|
121
121
|
- - "~>"
|
122
122
|
- !ruby/object:Gem::Version
|
123
123
|
version: '2.3'
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: filesize
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0.2'
|
131
|
+
type: :runtime
|
132
|
+
prerelease: false
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0.2'
|
124
138
|
- !ruby/object:Gem::Dependency
|
125
139
|
name: graphql-client
|
126
140
|
requirement: !ruby/object:Gem::Requirement
|