factbase 0.9.0 → 0.9.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9aeae89fbcf5e3c1b74f475a8ad001867869d29eab8b861a26b07a2fee9db93
4
- data.tar.gz: 0c20ed8b499cb495ca438621b30c24c9c837a73c8cffdde812ecacabc7b9a49c
3
+ metadata.gz: 2b0b91a22c7ec63e9ec1b98bc325006645243b11d2b0fa1ca591f005c5e7b34e
4
+ data.tar.gz: 60014d07339a593674ec768b63c99a4a993f7b22a0a6f1eb1386e8137c90db30
5
5
  SHA512:
6
- metadata.gz: 5f342a46704cdfa9f4355726fd7ca98f6a20d44090fd84c70e69189167abb97c378aca6f52fb295e736acbe4f501d61c65dd93ae833338327be8e81c9bb8f9a7
7
- data.tar.gz: 0ec8785757ba4a370e0b1f50b3a7d50271e5245278b23d1b6a45618c90676517bf45763af7f5b150c606c22571992fcd15a95e771e661d2f62308add8e97d93a
6
+ metadata.gz: 82e2abb7c56c198486d512ee9145c22399f01342107b4ebac14556977f87d8811908230522473b926057b04f355e890e391c313e488580cf1a1bb17b658e1dd7
7
+ data.tar.gz: 03225a085c0acb3d9bc57ddaf71ed4c2a878c1cafc88858b39ee0872ff29348ad28d772506eca16fbf6f2183e9a55ddb56e77899b49289f15d72bc92193d6b98
data/Gemfile CHANGED
@@ -6,11 +6,13 @@
6
6
  source 'https://rubygems.org'
7
7
  gemspec
8
8
 
9
- gem 'minitest', '5.25.4', require: false
9
+ gem 'minitest', '5.25.5', require: false
10
10
  gem 'minitest-reporters', '1.7.1', require: false
11
+ gem 'os', '>0', require: false
12
+ gem 'qbash', '>0', require: false
11
13
  gem 'rake', '13.2.1', require: false
12
14
  gem 'rspec-rails', '7.1.1', require: false
13
- gem 'rubocop', '1.73.2', require: false
15
+ gem 'rubocop', '1.74.0', require: false
14
16
  gem 'rubocop-minitest', '>0', require: false
15
17
  gem 'rubocop-performance', '>0', require: false
16
18
  gem 'rubocop-rake', '>0', require: false
data/Gemfile.lock CHANGED
@@ -14,9 +14,9 @@ PATH
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- actionpack (8.0.1)
18
- actionview (= 8.0.1)
19
- activesupport (= 8.0.1)
17
+ actionpack (8.0.2)
18
+ actionview (= 8.0.2)
19
+ activesupport (= 8.0.2)
20
20
  nokogiri (>= 1.8.5)
21
21
  rack (>= 2.2.4)
22
22
  rack-session (>= 1.0.1)
@@ -24,13 +24,13 @@ GEM
24
24
  rails-dom-testing (~> 2.2)
25
25
  rails-html-sanitizer (~> 1.6)
26
26
  useragent (~> 0.16)
27
- actionview (8.0.1)
28
- activesupport (= 8.0.1)
27
+ actionview (8.0.2)
28
+ activesupport (= 8.0.2)
29
29
  builder (~> 3.1)
30
30
  erubi (~> 1.11)
31
31
  rails-dom-testing (~> 2.2)
32
32
  rails-html-sanitizer (~> 1.6)
33
- activesupport (8.0.1)
33
+ activesupport (8.0.2)
34
34
  base64
35
35
  benchmark (>= 0.3)
36
36
  bigdecimal
@@ -58,6 +58,9 @@ GEM
58
58
  diff-lcs (1.6.0)
59
59
  docile (1.4.1)
60
60
  drb (2.2.1)
61
+ elapsed (0.0.1)
62
+ loog (> 0)
63
+ tago (> 0)
61
64
  erubi (1.13.1)
62
65
  i18n (1.14.7)
63
66
  concurrent-ruby (~> 1.0)
@@ -66,7 +69,7 @@ GEM
66
69
  pp (>= 0.6.0)
67
70
  rdoc (>= 4.0.0)
68
71
  reline (>= 0.4.2)
69
- json (2.10.1)
72
+ json (2.10.2)
70
73
  language_server-protocol (3.17.0.4)
71
74
  lint_roller (1.1.0)
72
75
  logger (1.6.6)
@@ -74,7 +77,7 @@ GEM
74
77
  crass (~> 1.0.2)
75
78
  nokogiri (>= 1.12.0)
76
79
  loog (0.6.0)
77
- minitest (5.25.4)
80
+ minitest (5.25.5)
78
81
  minitest-reporters (1.7.1)
79
82
  ansi
80
83
  builder
@@ -88,6 +91,7 @@ GEM
88
91
  racc (~> 1.4)
89
92
  nokogiri (1.18.3-x86_64-linux-gnu)
90
93
  racc (~> 1.4)
94
+ os (1.1.4)
91
95
  others (0.0.3)
92
96
  parallel (1.26.3)
93
97
  parser (3.3.7.1)
@@ -99,8 +103,13 @@ GEM
99
103
  psych (5.2.3)
100
104
  date
101
105
  stringio
106
+ qbash (0.4.0)
107
+ backtrace (> 0)
108
+ elapsed (> 0)
109
+ loog (> 0)
110
+ tago (> 0)
102
111
  racc (1.8.1)
103
- rack (3.1.11)
112
+ rack (3.1.12)
104
113
  rack-session (2.1.0)
105
114
  base64 (>= 0.1.0)
106
115
  rack (>= 3.0.0)
@@ -115,9 +124,9 @@ GEM
115
124
  rails-html-sanitizer (1.6.2)
116
125
  loofah (~> 2.21)
117
126
  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)
118
- railties (8.0.1)
119
- actionpack (= 8.0.1)
120
- activesupport (= 8.0.1)
127
+ railties (8.0.2)
128
+ actionpack (= 8.0.2)
129
+ activesupport (= 8.0.2)
121
130
  irb (~> 1.13)
122
131
  rackup (>= 1.0.0)
123
132
  rake (>= 12.2)
@@ -148,7 +157,7 @@ GEM
148
157
  rspec-mocks (~> 3.13)
149
158
  rspec-support (~> 3.13)
150
159
  rspec-support (3.13.2)
151
- rubocop (1.73.2)
160
+ rubocop (1.74.0)
152
161
  json (~> 2.3)
153
162
  language_server-protocol (~> 3.17.0.2)
154
163
  lint_roller (~> 1.1.0)
@@ -214,11 +223,13 @@ PLATFORMS
214
223
 
215
224
  DEPENDENCIES
216
225
  factbase!
217
- minitest (= 5.25.4)
226
+ minitest (= 5.25.5)
218
227
  minitest-reporters (= 1.7.1)
228
+ os (> 0)
229
+ qbash (> 0)
219
230
  rake (= 13.2.1)
220
231
  rspec-rails (= 7.1.1)
221
- rubocop (= 1.73.2)
232
+ rubocop (= 1.74.0)
222
233
  rubocop-minitest (> 0)
223
234
  rubocop-performance (> 0)
224
235
  rubocop-rake (> 0)
data/README.md CHANGED
@@ -209,33 +209,33 @@ This is the result of the benchmark:
209
209
  <!-- benchmark_begin -->
210
210
  ```text
211
211
  user system total real
212
- insert 20000 facts 0.561512 0.006100 0.567612 ( 0.567669)
213
- export 20000 facts 0.021207 0.001926 0.023133 ( 0.023136)
214
- import 411017 bytes (20000 facts) 0.030268 0.004025 0.034293 ( 0.034298)
215
- insert 10 facts 0.041799 0.003981 0.045780 ( 0.045783)
216
- query 10 times w/txn 1.949384 0.022040 1.971424 ( 1.971572)
217
- query 10 times w/o txn 0.766215 0.000000 0.766215 ( 0.766298)
218
- modify 10 attrs w/txn 1.831320 0.019013 1.850333 ( 1.850663)
219
- delete 10 facts w/txn 0.720217 0.000982 0.721199 ( 0.721265)
220
- (and (eq what 'issue-was-closed') (exists... -> 200 2.699199 0.003986 2.703185 ( 2.703395)
221
- (and (eq what 'issue-was-closed') (exists... -> 200/txn 2.711764 0.003998 2.715762 ( 2.716000)
222
- (and (eq what 'issue-was-closed') (exists... -> zero 4.091858 0.003001 4.094859 ( 4.095101)
223
- (and (eq what 'issue-was-closed') (exists... -> zero/txn 4.156396 0.003004 4.159400 ( 4.159589)
224
- (gt time '2024-03-23T03:21:43Z') 0.104266 0.001002 0.105268 ( 0.105284)
225
- (gt cost 50) 0.090716 0.000000 0.090716 ( 0.090721)
226
- (eq title 'Object Thinking 5000') 0.005533 0.000002 0.005535 ( 0.005536)
227
- (and (eq foo 42.998) (or (gt bar 200) (absent zzz))) 0.053251 0.000002 0.053253 ( 0.053255)
228
- (eq id (agg (always) (max id))) 0.300388 0.000000 0.300388 ( 0.300414)
229
- (join "c<=cost,b<=bar" (eq id (agg (always) (max id)))) 1.254507 0.002999 1.257506 ( 1.257555)
230
- delete! 0.051979 0.000000 0.051979 ( 0.051982)
231
- Taped.append() x50000 0.028540 0.000000 0.028540 ( 0.028543)
232
- Taped.each() x125 1.332618 0.000000 1.332618 ( 1.332645)
233
- Taped.delete_if() x375 0.815309 0.000000 0.815309 ( 0.815348)
212
+ insert 20000 facts 0.584859 0.005297 0.590156 ( 0.590186)
213
+ export 20000 facts 0.018342 0.005935 0.024277 ( 0.024282)
214
+ import 410974 bytes (20000 facts) 0.028027 0.004994 0.033021 ( 0.033026)
215
+ insert 10 facts 0.041771 0.000989 0.042760 ( 0.042763)
216
+ query 10 times w/txn 2.020294 0.038146 2.058440 ( 2.059555)
217
+ query 10 times w/o txn 0.727753 0.001014 0.728767 ( 0.728806)
218
+ modify 10 attrs w/txn 1.919959 0.014025 1.933984 ( 1.934328)
219
+ delete 10 facts w/txn 0.739267 0.000000 0.739267 ( 0.739299)
220
+ (and (eq what 'issue-was-closed') (exists... -> 200 2.717595 0.003012 2.720607 ( 2.720777)
221
+ (and (eq what 'issue-was-closed') (exists... -> 200/txn 2.732913 0.002012 2.734925 ( 2.735227)
222
+ (and (eq what 'issue-was-closed') (exists... -> zero 4.149053 0.001010 4.150063 ( 4.150436)
223
+ (and (eq what 'issue-was-closed') (exists... -> zero/txn 4.116972 0.001001 4.117973 ( 4.119644)
224
+ (gt time '2024-03-23T03:21:43Z') 0.107332 0.000002 0.107334 ( 0.107336)
225
+ (gt cost 50) 0.094454 0.000000 0.094454 ( 0.094458)
226
+ (eq title 'Object Thinking 5000') 0.003828 0.000000 0.003828 ( 0.003830)
227
+ (and (eq foo 42.998) (or (gt bar 200) (absent zzz))) 0.055983 0.000000 0.055983 ( 0.055986)
228
+ (eq id (agg (always) (max id))) 0.329920 0.001995 0.331915 ( 0.332005)
229
+ (join "c<=cost,b<=bar" (eq id (agg (always) (max id)))) 1.448262 0.002005 1.450267 ( 1.450350)
230
+ delete! 0.056928 0.000000 0.056928 ( 0.056932)
231
+ Taped.append() x50000 0.035070 0.001000 0.036070 ( 0.036074)
232
+ Taped.each() x125 1.310450 0.000000 1.310450 ( 1.310521)
233
+ Taped.delete_if() x375 0.819224 0.000001 0.819225 ( 0.819270)
234
234
  ```
235
235
 
236
236
  The results were calculated in [this GHA job][benchmark-gha]
237
- on 2025-03-12 at 08:03,
237
+ on 2025-03-14 at 09:14,
238
238
  on Linux with 4 CPUs.
239
239
  <!-- benchmark_end -->
240
240
 
241
- [benchmark-gha]: https://github.com/yegor256/factbase/actions/runs/13806425302
241
+ [benchmark-gha]: https://github.com/yegor256/factbase/actions/runs/13853425019
data/Rakefile CHANGED
@@ -3,9 +3,12 @@
3
3
  # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
+ require 'qbash'
6
7
  require 'rubygems'
7
8
  require 'rake'
8
9
  require 'rake/clean'
10
+ require 'shellwords'
11
+ require 'os'
9
12
 
10
13
  def name
11
14
  @name ||= File.basename(Dir['*.gemspec'].first, '.*')
@@ -15,7 +18,7 @@ def version
15
18
  Gem::Specification.load(Dir['*.gemspec'].first).version
16
19
  end
17
20
 
18
- task default: %i[clean test rubocop yard]
21
+ task default: %i[clean test picks reqs rubocop yard]
19
22
 
20
23
  require 'rake/testtask'
21
24
  desc 'Run all unit tests'
@@ -27,6 +30,22 @@ Rake::TestTask.new(:test) do |test|
27
30
  test.verbose = false
28
31
  end
29
32
 
33
+ desc 'Run them via Ruby, one by one'
34
+ task :picks do
35
+ next if OS.windows?
36
+ Dir['test/**/*.rb'].each do |f|
37
+ qbash("bundle exec ruby #{Shellwords.escape(f)}", log: $stdout)
38
+ end
39
+ end
40
+
41
+ desc 'Require them via Ruby, one by one'
42
+ task :reqs do
43
+ next if OS.windows?
44
+ Dir['lib/**/*.rb'].each do |f|
45
+ qbash("bundle exec ruby #{Shellwords.escape(f)}", log: $stdout)
46
+ end
47
+ end
48
+
30
49
  require 'yard'
31
50
  desc 'Build Yard documentation'
32
51
  YARD::Rake::YardocTask.new do |t|
data/lib/factbase/inv.rb CHANGED
@@ -8,6 +8,17 @@ require 'decoor'
8
8
  require_relative '../factbase'
9
9
 
10
10
  # A decorator of a Factbase, that checks invariants on every set.
11
+ #
12
+ # For example, you can use this decorator if you want to check that every
13
+ # fact has +when+:
14
+ #
15
+ # fb = Factbase::Inv.new(Factbase.new) do |f, fbt|
16
+ # assert !f['when'].nil?
17
+ # end
18
+ #
19
+ # The second argument passed to the block is the factbase, while the first
20
+ # one is the fact just touched.
21
+ #
11
22
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
12
23
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
13
24
  # License:: MIT
@@ -23,8 +34,8 @@ class Factbase::Inv
23
34
  Fact.new(@fb.insert, @block)
24
35
  end
25
36
 
26
- def query(query)
27
- Query.new(@fb.query(query), @block)
37
+ def query(query, maps = nil)
38
+ Query.new(@fb.query(query, maps), @block, self)
28
39
  end
29
40
 
30
41
  def txn
@@ -65,14 +76,15 @@ class Factbase::Inv
65
76
  class Query
66
77
  decoor(:query)
67
78
 
68
- def initialize(query, block)
79
+ def initialize(query, block, fb)
69
80
  @query = query
70
81
  @block = block
82
+ @fb = fb
71
83
  end
72
84
 
73
- def each
74
- return to_enum(__method__) unless block_given?
75
- @query.each do |f|
85
+ def each(fb = @fb, params = {})
86
+ return to_enum(__method__, fb, params) unless block_given?
87
+ @query.each(fb, params) do |f|
76
88
  yield Fact.new(f, @block)
77
89
  end
78
90
  end
@@ -22,7 +22,7 @@ class Factbase::Logged
22
22
  # @param [Print] tube The tube to use, if log is NIL
23
23
  def initialize(fb, log = nil, time_tolerate: 1, tube: nil)
24
24
  raise 'The "fb" is nil' if fb.nil?
25
- @fb = fb
25
+ @origin = fb
26
26
  if log.nil?
27
27
  raise 'Either "log" or "tube" must be non-NIL' if tube.nil?
28
28
  @tube = tube
@@ -31,17 +31,18 @@ class Factbase::Logged
31
31
  end
32
32
  end
33
33
 
34
- decoor(:fb)
34
+ decoor(:origin)
35
35
 
36
36
  def insert
37
37
  start = Time.now
38
- f = @fb.insert
39
- @tube.say(start, "Inserted new fact ##{@fb.size} in #{start.ago}")
38
+ f = @origin.insert
39
+ @tube.say(start, "Inserted new fact ##{@origin.size} in #{start.ago}")
40
40
  Fact.new(f, tube: @tube)
41
41
  end
42
42
 
43
- def query(query)
44
- Query.new(query, @tube, @fb)
43
+ def query(term, maps = nil)
44
+ term = to_term(term) if term.is_a?(String)
45
+ Query.new(term, maps, @tube, @origin)
45
46
  end
46
47
 
47
48
  def txn
@@ -49,7 +50,7 @@ class Factbase::Logged
49
50
  id = nil
50
51
  rollback = false
51
52
  r =
52
- @fb.txn do |fbt|
53
+ @origin.txn do |fbt|
53
54
  id = fbt.object_id
54
55
  yield Factbase::Logged.new(fbt, tube: @tube)
55
56
  rescue Factbase::Rollback => e
@@ -122,40 +123,25 @@ class Factbase::Logged
122
123
  # Query decorator.
123
124
  #
124
125
  # This is an internal class, it is not supposed to be instantiated directly.
125
- #
126
126
  class Query
127
- def initialize(expr, tube, fb)
128
- @expr = expr
127
+ def initialize(term, maps, tube, fb)
128
+ @term = term
129
+ @maps = maps
129
130
  @tube = tube
130
131
  @fb = fb
131
132
  end
132
133
 
133
- def one(fb = @fb, params = {})
134
- start = Time.now
135
- q = Factbase::Syntax.new(@expr).to_term.to_s
136
- r = nil
137
- tail =
138
- Factbase::Logged.elapsed do
139
- r = fb.query(@expr).one(fb, params)
140
- end
141
- if r.nil?
142
- @tube.say(start, "Nothing found by '#{q}' #{tail}")
143
- else
144
- @tube.say(start, "Found #{r} (#{r.class}) by '#{q}' #{tail}")
145
- end
146
- r
147
- end
148
-
149
- def each(fb = @fb, params = {}, &)
134
+ def each(fb = nil, params = {}, &)
135
+ return to_enum(__method__, fb, params) unless block_given?
150
136
  start = Time.now
151
- q = Factbase::Syntax.new(@expr).to_term.to_s
137
+ q = Factbase::Syntax.new(@term).to_term.to_s
152
138
  if block_given?
153
139
  r = nil
154
140
  tail =
155
141
  Factbase::Logged.elapsed do
156
- r = fb.query(@expr).each(fb, params, &)
142
+ r = @fb.query(@term, @maps).each(@fb, params, &)
157
143
  end
158
- raise ".each of #{@expr.class} returned #{r.class}" unless r.is_a?(Integer)
144
+ raise ".each of #{@term.class} returned #{r.class}" unless r.is_a?(Integer)
159
145
  if r.zero?
160
146
  @tube.say(start, "Nothing found by '#{q}' #{tail}")
161
147
  else
@@ -166,7 +152,7 @@ class Factbase::Logged
166
152
  array = []
167
153
  tail =
168
154
  Factbase::Logged.elapsed do
169
- fb.query(@expr).each(fb, params) do |f|
155
+ @fb.query(@term, @maps).each(@fb, params) do |f|
170
156
  array << f
171
157
  end
172
158
  end
@@ -179,21 +165,37 @@ class Factbase::Logged
179
165
  end
180
166
  end
181
167
 
182
- def delete!(fb = @fb)
168
+ def one(_fb = nil, params = {})
169
+ start = Time.now
170
+ q = Factbase::Syntax.new(@term).to_term.to_s
171
+ r = nil
172
+ tail =
173
+ Factbase::Logged.elapsed do
174
+ r = @fb.query(@term, @maps).one(@fb, params)
175
+ end
176
+ if r.nil?
177
+ @tube.say(start, "Nothing found by '#{q}' #{tail}")
178
+ else
179
+ @tube.say(start, "Found #{r} (#{r.class}) by '#{q}' #{tail}")
180
+ end
181
+ r
182
+ end
183
+
184
+ def delete!(_fb = nil)
183
185
  r = nil
184
186
  start = Time.now
185
- before = fb.size
187
+ before = @fb.size
186
188
  tail =
187
189
  Factbase::Logged.elapsed do
188
- r = @fb.query(@expr).delete!(fb)
190
+ r = @fb.query(@term).delete!(@fb)
189
191
  end
190
- raise ".delete! of #{@expr.class} returned #{r.class}" unless r.is_a?(Integer)
192
+ raise ".delete! of #{@term.class} returned #{r.class}" unless r.is_a?(Integer)
191
193
  if before.zero?
192
- @tube.say(start, "There were no facts, nothing deleted by '#{@expr}' #{tail}")
194
+ @tube.say(start, "There were no facts, nothing deleted by '#{@term}' #{tail}")
193
195
  elsif r.zero?
194
- @tube.say(start, "No facts out of #{before} deleted by '#{@expr}' #{tail}")
196
+ @tube.say(start, "No facts out of #{before} deleted by '#{@term}' #{tail}")
195
197
  else
196
- @tube.say(start, "Deleted #{r} fact(s) out of #{before} by '#{@expr}' #{tail}")
198
+ @tube.say(start, "Deleted #{r} fact(s) out of #{before} by '#{@term}' #{tail}")
197
199
  end
198
200
  r
199
201
  end
@@ -40,8 +40,8 @@ class Factbase::Rules
40
40
  Fact.new(@fb.insert, @check, @fb)
41
41
  end
42
42
 
43
- def query(query)
44
- Query.new(@fb.query(query), @check, @fb)
43
+ def query(query, maps = nil)
44
+ Query.new(@fb.query(query, maps), @check, @fb)
45
45
  end
46
46
 
47
47
  def txn
@@ -31,8 +31,8 @@ class Factbase::Tallied
31
31
  f
32
32
  end
33
33
 
34
- def query(query)
35
- Query.new(@fb.query(query), @churn, @fb)
34
+ def query(query, maps = nil)
35
+ Query.new(@fb.query(query, maps), @churn, @fb)
36
36
  end
37
37
 
38
38
  def txn
@@ -74,6 +74,14 @@ class Factbase::Taped
74
74
  @added = added
75
75
  end
76
76
 
77
+ def keys
78
+ @origin.keys
79
+ end
80
+
81
+ def map(&)
82
+ @origin.map(&)
83
+ end
84
+
77
85
  def [](key)
78
86
  v = @origin[key]
79
87
  v = TapedArray.new(v, @origin.object_id, @added) if v.is_a?(Array)
data/lib/factbase/term.rb CHANGED
@@ -45,37 +45,37 @@ class Factbase::Term
45
45
  attr_reader :operands
46
46
 
47
47
  require_relative 'terms/math'
48
- include Factbase::Term::Math
48
+ include Factbase::Math
49
49
 
50
50
  require_relative 'terms/logical'
51
- include Factbase::Term::Logical
51
+ include Factbase::Logical
52
52
 
53
53
  require_relative 'terms/aggregates'
54
- include Factbase::Term::Aggregates
54
+ include Factbase::Aggregates
55
55
 
56
56
  require_relative 'terms/strings'
57
- include Factbase::Term::Strings
57
+ include Factbase::Strings
58
58
 
59
59
  require_relative 'terms/casting'
60
- include Factbase::Term::Casting
60
+ include Factbase::Casting
61
61
 
62
62
  require_relative 'terms/meta'
63
- include Factbase::Term::Meta
63
+ include Factbase::Meta
64
64
 
65
65
  require_relative 'terms/aliases'
66
- include Factbase::Term::Aliases
66
+ include Factbase::Aliases
67
67
 
68
68
  require_relative 'terms/ordering'
69
- include Factbase::Term::Ordering
69
+ include Factbase::Ordering
70
70
 
71
71
  require_relative 'terms/defn'
72
- include Factbase::Term::Defn
72
+ include Factbase::Defn
73
73
 
74
74
  require_relative 'terms/system'
75
- include Factbase::Term::System
75
+ include Factbase::System
76
76
 
77
77
  require_relative 'terms/debug'
78
- include Factbase::Term::Debug
78
+ include Factbase::Debug
79
79
 
80
80
  # Ctor.
81
81
  # @param [Symbol] operator Operator
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Aggregates
13
+ module Factbase::Aggregates
14
14
  def min(_fact, maps, _fb)
15
15
  assert_args(1)
16
16
  _best(maps) { |v, b| v < b }
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Aliases
13
+ module Factbase::Aliases
14
14
  def as(fact, maps, fb)
15
15
  assert_args(2)
16
16
  a = @operands[0]
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Casting
13
+ module Factbase::Casting
14
14
  def to_string(fact, maps, fb)
15
15
  assert_args(1)
16
16
  vv = _values(0, fact, maps, fb)
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Debug
13
+ module Factbase::Debug
14
14
  def traced(fact, maps, fb)
15
15
  assert_args(1)
16
16
  t = @operands[0]
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Defn
13
+ module Factbase::Defn
14
14
  def defn(_fact, _maps, _fb)
15
15
  assert_args(2)
16
16
  fn = @operands[0]
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Logical
13
+ module Factbase::Logical
14
14
  # Always returns true, regardless of the fact
15
15
  # @param [Factbase::Fact] _fact The fact (unused)
16
16
  # @param [Array<Factbase::Fact>] _maps All maps available (unused)
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Math
13
+ module Factbase::Math
14
14
  def plus(fact, maps, fb)
15
15
  _arithmetic(:+, fact, maps, fb)
16
16
  end
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Meta
13
+ module Factbase::Meta
14
14
  def exists(fact, _maps, _fb)
15
15
  assert_args(1)
16
16
  !_by_symbol(0, fact).nil?
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Ordering
13
+ module Factbase::Ordering
14
14
  def prev(fact, maps, fb)
15
15
  assert_args(1)
16
16
  before = @prev
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::Strings
13
+ module Factbase::Strings
14
14
  def concat(fact, maps, fb)
15
15
  (0..@operands.length - 1).map { |i| _values(i, fact, maps, fb)&.first }.join
16
16
  end
@@ -10,7 +10,7 @@ require_relative '../../factbase'
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
11
  # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
12
  # License:: MIT
13
- module Factbase::Term::System
13
+ module Factbase::System
14
14
  def env(fact, maps, fb)
15
15
  assert_args(2)
16
16
  n = _values(0, fact, maps, fb)[0]
data/lib/factbase.rb CHANGED
@@ -82,7 +82,7 @@ require 'yaml'
82
82
  # License:: MIT
83
83
  class Factbase
84
84
  # Current version of the gem (changed by .rultor.yml on every release)
85
- VERSION = '0.9.0'
85
+ VERSION = '0.9.2' unless const_defined?(:VERSION)
86
86
 
87
87
  # An exception that may be thrown in a transaction, to roll it back.
88
88
  class Rollback < StandardError; end
@@ -3,6 +3,7 @@
3
3
  # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
+ require 'loog'
6
7
  require_relative '../../test__helper'
7
8
  require_relative '../../../lib/factbase/term'
8
9
  require_relative '../../../lib/factbase/syntax'
@@ -4,9 +4,15 @@
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require_relative '../test__helper'
7
+ require 'loog'
7
8
  require 'time'
8
9
  require_relative '../../lib/factbase'
9
10
  require_relative '../../lib/factbase/query'
11
+ require_relative '../../lib/factbase/logged'
12
+ require_relative '../../lib/factbase/pre'
13
+ require_relative '../../lib/factbase/inv'
14
+ require_relative '../../lib/factbase/rules'
15
+ require_relative '../../lib/factbase/tallied'
10
16
  require_relative '../../lib/factbase/cached/cached_factbase'
11
17
  require_relative '../../lib/factbase/indexed/indexed_factbase'
12
18
  require_relative '../../lib/factbase/sync/sync_factbase'
@@ -38,7 +44,12 @@ class TestQuery < Factbase::Test
38
44
  size = q['size']
39
45
  assert_equal(size, fb.query(qry).each.to_a.size, "#{base}: #{qry} at #{badge}")
40
46
  fb.txn do |fbt|
41
- assert_equal(size, fbt.query(qry).each.to_a.size, "#{base}: #{qry} at #{badge} (in txn)")
47
+ facts = fbt.query(qry).each.to_a
48
+ assert_equal(size, facts.size, "#{base}: #{qry} at #{badge} (in txn)")
49
+ facts.each do |fact|
50
+ refute_empty(fact.all_properties)
51
+ refute_nil(fact.to_s)
52
+ end
42
53
  end
43
54
  else
44
55
  ret = q['one']
@@ -227,13 +238,34 @@ class TestQuery < Factbase::Test
227
238
  def with_factbases(maps = [], &)
228
239
  {
229
240
  'plain' => Factbase.new(maps),
241
+ 'pre+plain' => Factbase::Pre.new(Factbase.new(maps)) { nil },
242
+ 'rules+plain' => Factbase::Rules.new(Factbase.new(maps), '(always)'),
243
+ 'inv+plain' => Factbase::Inv.new(Factbase.new(maps)) { nil },
230
244
  'sync+plain' => Factbase::SyncFactbase.new(Factbase.new(maps)),
245
+ 'tallied+plain' => Factbase::Tallied.new(Factbase.new(maps)),
231
246
  'indexed+plain' => Factbase::IndexedFactbase.new(Factbase.new(maps)),
232
247
  'cached+plain' => Factbase::CachedFactbase.new(Factbase.new(maps)),
248
+ 'logged+plain' => Factbase::Logged.new(Factbase.new(maps), Loog::NULL),
233
249
  'indexed+cached+plain' => Factbase::IndexedFactbase.new(Factbase::CachedFactbase.new(Factbase.new(maps))),
234
250
  'cached+indexed+plain' => Factbase::CachedFactbase.new(Factbase::IndexedFactbase.new(Factbase.new(maps))),
235
251
  'sync+cached+indexed+plain' => Factbase::SyncFactbase.new(
236
252
  Factbase::CachedFactbase.new(Factbase::IndexedFactbase.new(Factbase.new(maps)))
253
+ ),
254
+ 'all+plain' => Factbase::Tallied.new(
255
+ Factbase::Pre.new(
256
+ Factbase::Rules.new(
257
+ Factbase::Inv.new(
258
+ Factbase::SyncFactbase.new(
259
+ Factbase::CachedFactbase.new(
260
+ Factbase::IndexedFactbase.new(
261
+ Factbase.new(maps)
262
+ )
263
+ )
264
+ )
265
+ ) { nil },
266
+ '(always)'
267
+ )
268
+ ) { nil }
237
269
  )
238
270
  }.each(&)
239
271
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-12 00:00:00.000000000 Z
10
+ date: 2025-03-14 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: backtrace