factbase 0.5.0 → 0.5.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +12 -13
- data/README.md +10 -10
- data/lib/factbase/syntax.rb +9 -4
- data/lib/factbase.rb +1 -1
- data/test/factbase/test_syntax.rb +1 -0
- data/test/test_factbase.rb +8 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c672da652030c0c4a1405ce4d84b91e0ca776d342d1418be9b01d18ea6d70703
|
|
4
|
+
data.tar.gz: '068e446b24c80857c7c26724b22bd58d8644f8fa6db76223eb786d00fb422e1a'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f3cc8aae4d769dc4103a5501d4ff8e3093dbbdb0084b3f705d0b8d4dc70667f7828ae7bc39585e68c45891c94a926828e899110e34f3a76aad918e8acf9f319c
|
|
7
|
+
data.tar.gz: 062e0dc1dd5f90e5d9555baa2f2d79f957180d2a1c823a35bb296db43708d9feacb9f9b1465c0bfc411245aeba981dee0a902d22c806febf99f6676911354a7d
|
data/Gemfile.lock
CHANGED
|
@@ -14,23 +14,24 @@ PATH
|
|
|
14
14
|
GEM
|
|
15
15
|
remote: https://rubygems.org/
|
|
16
16
|
specs:
|
|
17
|
-
actionpack (
|
|
18
|
-
actionview (=
|
|
19
|
-
activesupport (=
|
|
17
|
+
actionpack (7.2.2.1)
|
|
18
|
+
actionview (= 7.2.2.1)
|
|
19
|
+
activesupport (= 7.2.2.1)
|
|
20
20
|
nokogiri (>= 1.8.5)
|
|
21
|
-
|
|
21
|
+
racc
|
|
22
|
+
rack (>= 2.2.4, < 3.2)
|
|
22
23
|
rack-session (>= 1.0.1)
|
|
23
24
|
rack-test (>= 0.6.3)
|
|
24
25
|
rails-dom-testing (~> 2.2)
|
|
25
26
|
rails-html-sanitizer (~> 1.6)
|
|
26
27
|
useragent (~> 0.16)
|
|
27
|
-
actionview (
|
|
28
|
-
activesupport (=
|
|
28
|
+
actionview (7.2.2.1)
|
|
29
|
+
activesupport (= 7.2.2.1)
|
|
29
30
|
builder (~> 3.1)
|
|
30
31
|
erubi (~> 1.11)
|
|
31
32
|
rails-dom-testing (~> 2.2)
|
|
32
33
|
rails-html-sanitizer (~> 1.6)
|
|
33
|
-
activesupport (
|
|
34
|
+
activesupport (7.2.2.1)
|
|
34
35
|
base64
|
|
35
36
|
benchmark (>= 0.3)
|
|
36
37
|
bigdecimal
|
|
@@ -42,7 +43,6 @@ GEM
|
|
|
42
43
|
minitest (>= 5.1)
|
|
43
44
|
securerandom (>= 0.3)
|
|
44
45
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
45
|
-
uri (>= 0.13.1)
|
|
46
46
|
ansi (1.5.0)
|
|
47
47
|
ast (2.4.2)
|
|
48
48
|
backtrace (0.4.0)
|
|
@@ -114,9 +114,9 @@ GEM
|
|
|
114
114
|
rails-html-sanitizer (1.6.2)
|
|
115
115
|
loofah (~> 2.21)
|
|
116
116
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
117
|
-
railties (
|
|
118
|
-
actionpack (=
|
|
119
|
-
activesupport (=
|
|
117
|
+
railties (7.2.2.1)
|
|
118
|
+
actionpack (= 7.2.2.1)
|
|
119
|
+
activesupport (= 7.2.2.1)
|
|
120
120
|
irb (~> 1.13)
|
|
121
121
|
rackup (>= 1.0.0)
|
|
122
122
|
rake (>= 12.2)
|
|
@@ -189,11 +189,10 @@ GEM
|
|
|
189
189
|
unicode-display_width (3.1.4)
|
|
190
190
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
|
191
191
|
unicode-emoji (4.0.4)
|
|
192
|
-
uri (1.0.2)
|
|
193
192
|
useragent (0.16.11)
|
|
194
193
|
yaml (0.4.0)
|
|
195
194
|
yard (0.9.37)
|
|
196
|
-
zeitwerk (2.
|
|
195
|
+
zeitwerk (2.6.18)
|
|
197
196
|
|
|
198
197
|
PLATFORMS
|
|
199
198
|
arm64-darwin-22
|
data/README.md
CHANGED
|
@@ -184,19 +184,19 @@ This is the result of the benchmark:
|
|
|
184
184
|
|
|
185
185
|
<!-- benchmark_begin -->
|
|
186
186
|
| Action | Seconds | Details |
|
|
187
|
-
| --- | --: |
|
|
188
|
-
| `fb.insert()` | 7.
|
|
189
|
-
| `(gt time '2024-03-23T03:21:43Z')` | 0.
|
|
190
|
-
| `(gt cost 50)` | 0.
|
|
191
|
-
| `(eq title 'Object Thinking 5000')` | 0.
|
|
192
|
-
| `(and (eq foo 42.998) (or (gt bar 200) (absent zzz)))` | 0.
|
|
187
|
+
| --- | --: | --- |
|
|
188
|
+
| `fb.insert()` | 7.874 | Inserted 100000 facts |
|
|
189
|
+
| `(gt time '2024-03-23T03:21:43Z')` | 0.072 | Found 100000 fact(s) |
|
|
190
|
+
| `(gt cost 50)` | 0.069 | Found 50030 fact(s) |
|
|
191
|
+
| `(eq title 'Object Thinking 5000')` | 0.051 | Found 1 fact(s) |
|
|
192
|
+
| `(and (eq foo 42.998) (or (gt bar 200) (absent zzz)))` | 0.059 | Found 2 fact(s) |
|
|
193
193
|
| `(eq id (agg (always) (max id)))` | 0.131 | Found 1 fact(s) |
|
|
194
|
-
| `(join "c<=cost,b<=bar" (eq id (agg (always) (max id))))` | 0.
|
|
195
|
-
| `.export()` + `.import()` |
|
|
194
|
+
| `(join "c<=cost,b<=bar" (eq id (agg (always) (max id))))` | 0.695 | Found 100000 fact(s) |
|
|
195
|
+
| `.export()` + `.import()` | 1.931 | 11407636 bytes |
|
|
196
196
|
|
|
197
197
|
The results were calculated in [this GHA job][benchmark-gha]
|
|
198
|
-
on 2025-01-27 at 16:
|
|
198
|
+
on 2025-01-27 at 16:51,
|
|
199
199
|
on Linux with 4 CPUs.
|
|
200
200
|
<!-- benchmark_end -->
|
|
201
201
|
|
|
202
|
-
[benchmark-gha]: https://github.com/yegor256/factbase/actions/runs/
|
|
202
|
+
[benchmark-gha]: https://github.com/yegor256/factbase/actions/runs/12994018323
|
data/lib/factbase/syntax.rb
CHANGED
|
@@ -45,6 +45,11 @@ require_relative 'term_once'
|
|
|
45
45
|
# License:: MIT
|
|
46
46
|
class Factbase::Syntax
|
|
47
47
|
# Ctor.
|
|
48
|
+
#
|
|
49
|
+
# The class provided as the +term+ argument must have a three-argument
|
|
50
|
+
# constructor, similar to the class +Factbase::Term+. Also, it must be
|
|
51
|
+
# a child of +Factbase::Term+.
|
|
52
|
+
#
|
|
48
53
|
# @param [Factbase] fb Factbase
|
|
49
54
|
# @param [String] query The query, for example "(eq id 42)"
|
|
50
55
|
# @param [Class] term The class to instantiate to make every term
|
|
@@ -64,7 +69,7 @@ class Factbase::Syntax
|
|
|
64
69
|
t
|
|
65
70
|
end
|
|
66
71
|
rescue StandardError => e
|
|
67
|
-
err = "#{e.message} (#{e.backtrace
|
|
72
|
+
err = "#{e.message} (#{e.backtrace.take(5).join('; ')}) in \"#{@query}\""
|
|
68
73
|
err = "#{err}, tokens: #{@tokens}" unless @tokens.nil?
|
|
69
74
|
raise err
|
|
70
75
|
end
|
|
@@ -77,10 +82,10 @@ class Factbase::Syntax
|
|
|
77
82
|
@tokens ||= to_tokens
|
|
78
83
|
raise 'No tokens' if @tokens.empty?
|
|
79
84
|
@ast ||= to_ast(@tokens, 0)
|
|
80
|
-
raise
|
|
85
|
+
raise "Too many terms (#{@ast[1]} != #{@tokens.size})" if @ast[1] != @tokens.size
|
|
81
86
|
term = @ast[0]
|
|
82
87
|
raise 'No terms found' if term.nil?
|
|
83
|
-
raise
|
|
88
|
+
raise "Not a term: #{@term.class.name.inspect}" unless term.is_a?(@term)
|
|
84
89
|
term
|
|
85
90
|
end
|
|
86
91
|
|
|
@@ -164,7 +169,7 @@ class Factbase::Syntax
|
|
|
164
169
|
elsif t.match?(/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$/)
|
|
165
170
|
Time.parse(t)
|
|
166
171
|
else
|
|
167
|
-
raise "Wrong symbol format (#{t})" unless t.match?(/^[_a-z
|
|
172
|
+
raise "Wrong symbol format (#{t})" unless t.match?(/^([_a-z][a-zA-Z0-9_]*|\$[a-z]+)$/)
|
|
168
173
|
t.to_sym
|
|
169
174
|
end
|
|
170
175
|
end
|
data/lib/factbase.rb
CHANGED
|
@@ -81,7 +81,7 @@ require 'yaml'
|
|
|
81
81
|
# License:: MIT
|
|
82
82
|
class Factbase
|
|
83
83
|
# Current version of the gem (changed by .rultor.yml on every release)
|
|
84
|
-
VERSION = '0.5.
|
|
84
|
+
VERSION = '0.5.1'
|
|
85
85
|
|
|
86
86
|
# An exception that may be thrown in a transaction, to roll it back.
|
|
87
87
|
class Rollback < StandardError; end
|
data/test/test_factbase.rb
CHANGED
|
@@ -294,20 +294,21 @@ class TestFactbase < Minitest::Test
|
|
|
294
294
|
# See details here https://github.com/yegor256/factbase/actions/runs/10492255419/job/29068637032
|
|
295
295
|
def test_concurrent_transactions_inserts
|
|
296
296
|
skip('Does not work')
|
|
297
|
+
total = 100
|
|
297
298
|
fb = Factbase.new
|
|
298
|
-
Threads.new(
|
|
299
|
+
Threads.new(total).assert do |i|
|
|
299
300
|
fb.txn do |fbt|
|
|
300
301
|
fact = fbt.insert
|
|
301
302
|
fact.thread_id = i
|
|
302
303
|
end
|
|
303
304
|
end
|
|
304
|
-
assert_equal(
|
|
305
|
-
assert_equal(
|
|
305
|
+
assert_equal(total, fb.size)
|
|
306
|
+
assert_equal(total, fb.query('(exists thread_id)').each.to_a.size)
|
|
306
307
|
end
|
|
307
308
|
|
|
308
309
|
def test_concurrent_transactions_with_rollbacks
|
|
309
310
|
fb = Factbase.new
|
|
310
|
-
Threads.new
|
|
311
|
+
Threads.new.assert do |i|
|
|
311
312
|
fb.txn do |fbt|
|
|
312
313
|
fact = fbt.insert
|
|
313
314
|
fact.thread_id = i
|
|
@@ -319,7 +320,8 @@ class TestFactbase < Minitest::Test
|
|
|
319
320
|
|
|
320
321
|
def test_concurrent_transactions_successful
|
|
321
322
|
fb = Factbase.new
|
|
322
|
-
|
|
323
|
+
total = 100
|
|
324
|
+
Threads.new(total).assert do |i|
|
|
323
325
|
fb.txn do |fbt|
|
|
324
326
|
fact = fbt.insert
|
|
325
327
|
fact.thread_id = i
|
|
@@ -327,7 +329,7 @@ class TestFactbase < Minitest::Test
|
|
|
327
329
|
end
|
|
328
330
|
end
|
|
329
331
|
facts = fb.query('(exists thread_id)').each.to_a
|
|
330
|
-
assert_equal(
|
|
332
|
+
assert_equal(total, facts.size)
|
|
331
333
|
facts.each do |fact|
|
|
332
334
|
assert_equal(fact.value, fact.thread_id * 10)
|
|
333
335
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: factbase
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yegor Bugayenko
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-01-
|
|
11
|
+
date: 2025-01-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: backtrace
|