factbase 0.0.42 → 0.0.44

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: 42066d9d82538ecb6f0ec8df6cc711f4328e1ba496f00366fe67719ca8a1185e
4
- data.tar.gz: d40e21b7e426af5184b9b03f515da4508b1e1e9e52995f566b16c778eefefca3
3
+ metadata.gz: 7942029d876a9fee77f167bb9e9d7311445e16fa38c9654dfd6eae231fb9c366
4
+ data.tar.gz: 102f08927aafc6900d4563e90cbabb9311166307e1ca57a9bd4e484ff8be684a
5
5
  SHA512:
6
- metadata.gz: ff04d1f7e3eb1b18b36544ea8fb61280cda250a5e9920ba7b858092ae7c13111efce537d39acd7119f2f70c8704a89d06c98bf54b5a4639b4f187599f61eecbc
7
- data.tar.gz: '09ba7d04f933f758c1db716c9490d464a2202644560a594bfae0a77e8bee8d26dcc38605101417a062ccd5c9645b5187e7f069e8f31e6bc782e48dc79775a347'
6
+ metadata.gz: d6877f4b3dbe627819256cda88214fd170e89e37521c2936daa0fed5a02b1450fc98157c53e92d2f38e48522dd617d901609ec1b23b96875abb68a7c231d5a47
7
+ data.tar.gz: 482f13ec05d51bf726049ed44627ec2719ee17b1a5b387eb7ebb6ee98a760523702f9f81540e6e10ff2dc211a90321742c5796cb63ef9ee4aa64fa6777886b81
@@ -53,11 +53,14 @@ class Factbase::Rules
53
53
  def txn(this = self, &)
54
54
  before = @check
55
55
  @check = Blind.new
56
- @fb.txn(this, &)
56
+ modified = @fb.txn(this, &)
57
57
  @check = before
58
- @fb.query('(always)').each do |f|
59
- @check.it(f)
58
+ if modified
59
+ @fb.query('(always)').each do |f|
60
+ @check.it(f)
61
+ end
60
62
  end
63
+ modified
61
64
  end
62
65
 
63
66
  def export
@@ -21,7 +21,6 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'json'
24
- require 'time'
25
24
  require_relative '../factbase'
26
25
 
27
26
  # Factbase to JSON converter.
@@ -37,14 +36,15 @@ require_relative '../factbase'
37
36
  # License:: MIT
38
37
  class Factbase::ToJSON
39
38
  # Constructor.
40
- def initialize(fb)
39
+ def initialize(fb, sorter = '_id')
41
40
  @fb = fb
41
+ @sorter = sorter
42
42
  end
43
43
 
44
44
  # Convert the entire factbase into JSON.
45
45
  # @return [String] The factbase in JSON format
46
46
  def json
47
47
  maps = Marshal.load(@fb.export)
48
- maps.map { |m| m.sort.to_h }.to_json
48
+ maps.sort_by { |m| m[@sorter] }.map { |m| m.sort.to_h }.to_json
49
49
  end
50
50
  end
@@ -37,8 +37,9 @@ require_relative '../factbase'
37
37
  # License:: MIT
38
38
  class Factbase::ToXML
39
39
  # Constructor.
40
- def initialize(fb)
40
+ def initialize(fb, sorter = '_id')
41
41
  @fb = fb
42
+ @sorter = sorter
42
43
  end
43
44
 
44
45
  # Convert the entire factbase into XML.
@@ -48,12 +49,11 @@ class Factbase::ToXML
48
49
  maps = Marshal.load(bytes)
49
50
  meta = {
50
51
  version: Factbase::VERSION,
51
- dob: Time.now.utc.iso8601,
52
52
  size: bytes.size
53
53
  }
54
54
  Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
55
55
  xml.fb(meta) do
56
- maps.each do |m|
56
+ maps.sort_by { |m| m[@sorter] }.each do |m|
57
57
  xml.f_ do
58
58
  m.sort.to_h.each do |k, vv|
59
59
  if vv.is_a?(Array)
@@ -21,7 +21,6 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'yaml'
24
- require 'time'
25
24
  require_relative '../factbase'
26
25
 
27
26
  # Factbase to YAML converter.
@@ -37,14 +36,15 @@ require_relative '../factbase'
37
36
  # License:: MIT
38
37
  class Factbase::ToYAML
39
38
  # Constructor.
40
- def initialize(fb)
39
+ def initialize(fb, sorter = '_id')
41
40
  @fb = fb
41
+ @sorter = sorter
42
42
  end
43
43
 
44
44
  # Convert the entire factbase into YAML.
45
45
  # @return [String] The factbase in YAML format
46
46
  def yaml
47
47
  maps = Marshal.load(@fb.export)
48
- YAML.dump({ 'facts' => maps.map { |m| m.sort.to_h } })
48
+ YAML.dump({ 'facts' => maps.sort_by { |m| m[@sorter] }.map { |m| m.sort.to_h } })
49
49
  end
50
50
  end
data/lib/factbase.rb CHANGED
@@ -79,7 +79,7 @@ require 'yaml'
79
79
  # License:: MIT
80
80
  class Factbase
81
81
  # Current version of the gem (changed by .rultor.yml on every release)
82
- VERSION = '0.0.42'
82
+ VERSION = '0.0.44'
83
83
 
84
84
  # An exception that may be thrown in a transaction, to roll it back.
85
85
  class Rollback < StandardError; end
@@ -159,22 +159,30 @@ class Factbase
159
159
  # inserted and all changes that happened in the block will be rolled back.
160
160
  #
161
161
  # @param [Factbase] this The factbase to use (don't provide this param)
162
+ # @return [Boolean] TRUE if some changes have been made, FALSE otherwise
162
163
  def txn(this = self)
163
164
  copy = this.dup
164
165
  begin
165
166
  yield copy
166
167
  rescue Factbase::Rollback
167
- return
168
+ return false
168
169
  end
170
+ modified = false
169
171
  @mutex.synchronize do
170
172
  after = Marshal.load(copy.export)
171
173
  after.each_with_index do |m, i|
172
- @maps << {} if i >= @maps.size
174
+ if i >= @maps.size
175
+ @maps << {}
176
+ modified = true
177
+ end
173
178
  m.each do |k, v|
179
+ next if @maps[i][k] == v
174
180
  @maps[i][k] = v
181
+ modified = true
175
182
  end
176
183
  end
177
184
  end
185
+ modified
178
186
  end
179
187
 
180
188
  # Export it into a chain of bytes.
@@ -22,6 +22,7 @@
22
22
 
23
23
  require 'minitest/autorun'
24
24
  require_relative '../../lib/factbase/term'
25
+ require_relative '../../lib/factbase/syntax'
25
26
 
26
27
  # Term test.
27
28
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -227,6 +228,27 @@ class TestTerm < Minitest::Test
227
228
  assert(msg.include?('at (at)'), msg)
228
229
  end
229
230
 
231
+ def test_aggregation
232
+ maps = [
233
+ { 'x' => 1, 'y' => 0, 'z' => 4 },
234
+ { 'x' => 2, 'y' => 42, 'z' => 3 },
235
+ { 'x' => 3, 'y' => 42, 'z' => 5 },
236
+ { 'x' => 4, 'y' => 42, 'z' => 2 },
237
+ { 'x' => 5, 'y' => 42, 'z' => 1 },
238
+ { 'x' => 8, 'y' => 0, 'z' => 6 }
239
+ ]
240
+ {
241
+ '(eq x (agg (eq y 42) (min x)))' => '(eq x 2)',
242
+ '(eq z (agg (eq y 0) (max z)))' => '(eq x 8)',
243
+ '(eq x (agg (and (eq y 42) (gt z 1)) (max x)))' => '(eq x 4)',
244
+ '(and (eq x (agg (eq y 42) (min x))) (eq z 3))' => '(eq x 2)'
245
+ }.each do |q, r|
246
+ t = Factbase::Syntax.new(q).to_term
247
+ f = maps.find { |m| t.evaluate(fact(m), maps) }
248
+ assert(Factbase::Syntax.new(r).to_term.evaluate(fact(f), []))
249
+ end
250
+ end
251
+
230
252
  private
231
253
 
232
254
  def fact(map = {})
@@ -56,7 +56,6 @@ class TestToXML < Minitest::Test
56
56
  fb.insert.x = 42
57
57
  to = Factbase::ToXML.new(fb)
58
58
  xml = Nokogiri::XML.parse(to.xml)
59
- assert(!xml.xpath('/fb[@dob]').empty?)
60
59
  assert(!xml.xpath('/fb[@version]').empty?)
61
60
  assert(!xml.xpath('/fb[@size]').empty?)
62
61
  end
@@ -33,9 +33,10 @@ class TestToYAML < Minitest::Test
33
33
  def test_simple_rendering
34
34
  fb = Factbase.new
35
35
  f = fb.insert
36
+ f._id = 1
36
37
  f.foo = 42
37
38
  f.foo = 256
38
- fb.insert
39
+ fb.insert._id = 2
39
40
  to = Factbase::ToYAML.new(fb)
40
41
  yaml = YAML.load(to.yaml)
41
42
  assert_equal(2, yaml['facts'].size)
@@ -143,10 +143,11 @@ class TestFactbase < Minitest::Test
143
143
 
144
144
  def test_txn_with_rollback
145
145
  fb = Factbase.new
146
- fb.txn do |fbt|
146
+ modified = fb.txn do |fbt|
147
147
  fbt.insert.bar = 33
148
148
  raise Factbase::Rollback
149
149
  end
150
+ assert(!modified)
150
151
  assert_equal(0, fb.query('(always)').each.to_a.size)
151
152
  end
152
153
  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.0.42
4
+ version: 0.0.44
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-04 00:00:00.000000000 Z
11
+ date: 2024-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json