factbase 0.15.8 → 0.16.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8a08255776b850ff21a081e627196da1696622452c9953f331f3e585cd2877b
4
- data.tar.gz: 6a0dd5bbd7cf3dd7fcd418297d189be1808474685111946c991bc9415d59c4d2
3
+ metadata.gz: 96133055dc92095960ab4b258f4a144105393d2a86e11f96c3199ff24d35653a
4
+ data.tar.gz: f93590d550bf7b54aaa235e43557173d57af37abdc9e0a37491cf68c654e2c1e
5
5
  SHA512:
6
- metadata.gz: 0b4151e52ef377a639025b96e0136dab4b56320d73773dfa15396f3267ae0a310c71e45f82115fe36e59b1c6cd34831e401e91062c279ac7bfefa278a940f471
7
- data.tar.gz: d773f631b328ac501a1d19d18f671cb1637ea3b7ee4df684256ddd07b45ef2e84826b52441d6c4a0b57f24d95a7821fe57cf251887884b98f0b0c4a2961eeeb3
6
+ metadata.gz: 2a532d7b59b0fa32d5662c420fb1d0de409d1c9cdf52fd6cf42c3020fd20a2008679019cf853a49e7ac1b0c9207d87134ffe1f23693f652a99188c8c6bd518f2
7
+ data.tar.gz: 67df97f44bdfbbcdba5cb5b7cec6a2f62cf9b4049f0a3d643382d797d9ec2997160ac231e871a18642c8fbd903387412e6c741d367f4e4362019d3a45a4cf6e3
data/Gemfile.lock CHANGED
@@ -72,7 +72,7 @@ GEM
72
72
  psych (>= 4.0.0)
73
73
  regexp_parser (2.11.2)
74
74
  rexml (3.4.2)
75
- rubocop (1.80.1)
75
+ rubocop (1.80.2)
76
76
  json (~> 2.3)
77
77
  language_server-protocol (~> 3.17.0.2)
78
78
  lint_roller (~> 1.1.0)
data/README.md CHANGED
@@ -176,6 +176,12 @@ It's also possible to use a sub-query in a shorter form than with the `agg`:
176
176
 
177
177
  * `(empty q)` is true if the subquery `q` is empty
178
178
 
179
+ It's possible to post-process a list of facts, for `agg` and `join`:
180
+
181
+ * `(sorted p expr)` sorts them by the value of `p` property
182
+ * `(inverted expr)` reverses them
183
+ * `(head n expr)` takes only `n` facts from the head of the list
184
+
179
185
  There are some system-level terms:
180
186
 
181
187
  * `(env v1 v2)` returns the value of environment variable `v1` or the string
@@ -17,6 +17,7 @@ module Factbase::CachedTerm
17
17
  # @return [bool] TRUE if matches
18
18
  def evaluate(fact, maps, fb)
19
19
  return super unless static? && !abstract?
20
+ return super if %i[head unique].include?(@op)
20
21
  key = [maps.object_id, to_s]
21
22
  before = @cache[key]
22
23
  @cache[key] = super if before.nil?
@@ -19,7 +19,7 @@ module Factbase::IndexedTerm
19
19
  # @param [Array<Hash>] maps Array of facts
20
20
  # @param [Hash] params Key/value params to use
21
21
  # @return [Array<Hash>|nil] Returns a new array, or NIL if the original array must be used
22
- def predict(maps, params)
22
+ def predict(maps, fb, params)
23
23
  key = [maps.object_id, @operands.first, @op]
24
24
  case @op
25
25
  when :one
@@ -144,7 +144,7 @@ module Factbase::IndexedTerm
144
144
  r = (maps & []) | j
145
145
  else
146
146
  @operands.each do |o|
147
- n = o.predict(maps, params)
147
+ n = o.predict(maps, fb, params)
148
148
  break if n.nil?
149
149
  if r.nil?
150
150
  r = n
@@ -159,7 +159,7 @@ module Factbase::IndexedTerm
159
159
  when :or
160
160
  r = nil
161
161
  @operands.each do |o|
162
- n = o.predict(maps, params)
162
+ n = o.predict(maps, fb, params)
163
163
  if n.nil?
164
164
  r = nil
165
165
  break
@@ -171,7 +171,7 @@ module Factbase::IndexedTerm
171
171
  r
172
172
  when :not
173
173
  if @idx[key].nil?
174
- yes = @operands.first.predict(maps, params)
174
+ yes = @operands.first.predict(maps, fb, params)
175
175
  if yes.nil?
176
176
  @idx[key] = { r: nil }
177
177
  else
@@ -44,7 +44,7 @@ class Factbase::Query
44
44
  return to_enum(__method__, fb, params) unless block_given?
45
45
  yielded = 0
46
46
  params = params.transform_keys(&:to_s) if params.is_a?(Hash)
47
- maybe = @term.predict(@maps, Factbase::Tee.new({}, params))
47
+ maybe = @term.predict(@maps, fb, Factbase::Tee.new({}, params))
48
48
  maybe ||= @maps unless maybe.equal?(@maps)
49
49
  maybe.each do |m|
50
50
  extras = {}
data/lib/factbase/tee.rb CHANGED
@@ -27,7 +27,8 @@ class Factbase::Tee
27
27
  end
28
28
 
29
29
  def all_properties
30
- @fact.all_properties + (@upper.is_a?(Hash) ? @upper.keys : @upper.all_properties)
30
+ (@fact.is_a?(Hash) ? @fact.keys : @fact.all_properties) +
31
+ (@upper.is_a?(Hash) ? @upper.keys : @upper.all_properties)
31
32
  end
32
33
 
33
34
  others do |*args|
data/lib/factbase/term.rb CHANGED
@@ -53,6 +53,9 @@ class Factbase::Term
53
53
  require_relative 'terms/aggregates'
54
54
  include Factbase::Aggregates
55
55
 
56
+ require_relative 'terms/lists'
57
+ include Factbase::Lists
58
+
56
59
  require_relative 'terms/strings'
57
60
  include Factbase::Strings
58
61
 
@@ -107,8 +110,13 @@ class Factbase::Term
107
110
  # @param [Array<Hash>] maps Records to iterate, maybe
108
111
  # @param [Hash] _params Params to use (keys must be strings, not symbols, with values as arrays)
109
112
  # @return [Array<Hash>] Records to iterate
110
- def predict(maps, _params)
111
- maps
113
+ def predict(maps, fb, params)
114
+ m = :"#{@op}_predict"
115
+ if respond_to?(m)
116
+ send(m, maps, fb, params)
117
+ else
118
+ maps
119
+ end
112
120
  end
113
121
 
114
122
  # Does it match the fact?
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
+ # SPDX-License-Identifier: MIT
5
+
6
+ require_relative '../../factbase'
7
+
8
+ # Lists management.
9
+ #
10
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
+ # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
+ # License:: MIT
13
+ module Factbase::Lists
14
+ def sorted(_fact, _maps, _fb)
15
+ true
16
+ end
17
+
18
+ def sorted_predict(maps, fb, params)
19
+ assert_args(2)
20
+ prop = @operands[0]
21
+ raise "A symbol is expected as first argument of 'sorted'" unless prop.is_a?(Symbol)
22
+ term = @operands[1]
23
+ raise "A term is expected, but '#{term}' provided" unless term.is_a?(Factbase::Term)
24
+ fb.query(term, maps).each(fb, params).to_a
25
+ .reject { |m| m[prop].nil? }
26
+ .sort_by { |m| m[prop].first }
27
+ .map { |m| m.all_properties.to_h { |k| [k, m[k]] } }
28
+ end
29
+
30
+ def inverted(_fact, _maps, _fb)
31
+ true
32
+ end
33
+
34
+ def inverted_predict(maps, fb, params)
35
+ assert_args(1)
36
+ term = @operands[0]
37
+ raise "A term is expected, but '#{term}' provided" unless term.is_a?(Factbase::Term)
38
+ fb.query(term, maps).each(fb, params).to_a
39
+ .reverse
40
+ .map { |m| m.all_properties.to_h { |k| [k, m[k]] } }
41
+ end
42
+ end
@@ -31,4 +31,12 @@ module Factbase::Ordering
31
31
  end
32
32
  pass
33
33
  end
34
+
35
+ def head(*)
36
+ max = @operands[0]
37
+ raise "An integer is expected as first argument of 'head'" unless max.is_a?(Integer)
38
+ @passed = 0 if @passed.nil?
39
+ @passed += 1
40
+ @passed <= max
41
+ end
34
42
  end
@@ -9,5 +9,5 @@
9
9
  # License:: MIT
10
10
  class Factbase
11
11
  # Current version of the gem (changed by .rultor.yml on every release)
12
- VERSION = '0.15.8' unless const_defined?(:VERSION)
12
+ VERSION = '0.16.0' unless const_defined?(:VERSION)
13
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.8
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -202,6 +202,7 @@ files:
202
202
  - lib/factbase/terms/casting.rb
203
203
  - lib/factbase/terms/debug.rb
204
204
  - lib/factbase/terms/defn.rb
205
+ - lib/factbase/terms/lists.rb
205
206
  - lib/factbase/terms/logical.rb
206
207
  - lib/factbase/terms/math.rb
207
208
  - lib/factbase/terms/meta.rb