factbase 0.0.49 → 0.0.50

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: 19ec04ca7c6bf83d50a09c6325e396685e6eb0d2590a4ffca5ccee1fcafa45f1
4
- data.tar.gz: 3550dd7bff7f9ad854689b5c78571211454bf34c09ec0b32fd4b240fc509939c
3
+ metadata.gz: f62ac48c3d2c181b0064e519947fa2fed0ecb0b81660663c91319233eb2fc529
4
+ data.tar.gz: f3131120095c0ece6cb01313bad9f55d58145ee289dfc4a4f8bd7e949778521b
5
5
  SHA512:
6
- metadata.gz: 5d2aa256c677f5d93fb9d41cfbe2548d83ebce3490da521d4a920f06ec774305c5850dc4dea71c76df2e2cda827db3c0292b21f0dae8dc9cee136e6e4cdfb3d3
7
- data.tar.gz: 0e96d7968129d750e5e71940ff5f114bdd920b7ae417ad87cbcea1ef7746c66142c9f1e312980a08cdf2e4ec259747ea6da7f268b6f70c4292225a3b4e6d775d
6
+ metadata.gz: d7325ad6538622ef5e8764547314ac2970827b44eb70dd37acde333505bd630370bf4ccfe7d1b35916592b89b4dd346c82bcb0c2f2d7532994cfbef0d2a23467
7
+ data.tar.gz: eb8554fb580ec058551d6f4f43e47dac22ff13ee427195595a1d9f40caf7f51c59c0c697a849136618a625addf82f726b658752caf755b7eab84b3482a0a8b28
@@ -32,7 +32,7 @@ jobs:
32
32
  strategy:
33
33
  matrix:
34
34
  os: [ubuntu-20.04, macos-12, windows-2022]
35
- ruby: [3.2, 3.3]
35
+ ruby: [3.2]
36
36
  runs-on: ${{ matrix.os }}
37
37
  steps:
38
38
  - uses: actions/checkout@v4
data/Gemfile.lock CHANGED
@@ -71,13 +71,13 @@ GEM
71
71
  nokogiri (1.16.5-x86_64-linux)
72
72
  racc (~> 1.4)
73
73
  parallel (1.25.1)
74
- parser (3.3.2.0)
74
+ parser (3.3.3.0)
75
75
  ast (~> 2.4.1)
76
76
  racc
77
77
  psych (5.1.2)
78
78
  stringio
79
79
  racc (1.8.0)
80
- rack (3.1.0)
80
+ rack (3.1.3)
81
81
  rack-session (2.0.0)
82
82
  rack (>= 3.0.0)
83
83
  rack-test (2.1.0)
@@ -105,7 +105,7 @@ GEM
105
105
  rdoc (6.7.0)
106
106
  psych (>= 4.0.0)
107
107
  regexp_parser (2.9.2)
108
- reline (0.5.8)
108
+ reline (0.5.9)
109
109
  io-console (~> 0.5)
110
110
  rexml (3.3.0)
111
111
  strscan
@@ -141,8 +141,8 @@ GEM
141
141
  parser (>= 3.3.1.0)
142
142
  rubocop-capybara (2.21.0)
143
143
  rubocop (~> 1.41)
144
- rubocop-factory_bot (2.26.0)
145
- rubocop (~> 1.41)
144
+ rubocop-factory_bot (2.26.1)
145
+ rubocop (~> 1.61)
146
146
  rubocop-performance (1.21.0)
147
147
  rubocop (>= 1.48.1, < 2.0)
148
148
  rubocop-ast (>= 1.31.1, < 2.0)
@@ -151,8 +151,8 @@ GEM
151
151
  rubocop-capybara (~> 2.17)
152
152
  rubocop-factory_bot (~> 2.22)
153
153
  rubocop-rspec_rails (~> 2.28)
154
- rubocop-rspec_rails (2.29.0)
155
- rubocop (~> 1.40)
154
+ rubocop-rspec_rails (2.29.1)
155
+ rubocop (~> 1.61)
156
156
  ruby-progressbar (1.13.0)
157
157
  simplecov (0.22.0)
158
158
  docile (~> 1.1)
@@ -165,7 +165,7 @@ GEM
165
165
  simplecov_json_formatter (0.1.4)
166
166
  stringio (3.1.0)
167
167
  strscan (3.1.0)
168
- tago (0.0.1)
168
+ tago (0.0.2)
169
169
  thor (1.3.1)
170
170
  tzinfo (2.0.6)
171
171
  concurrent-ruby (~> 1.0)
@@ -54,17 +54,22 @@ class Factbase::Looged
54
54
  end
55
55
 
56
56
  def txn(this = self, &)
57
+ start = Time.now
57
58
  before = @fb.size
58
- tail = nil
59
+ id = nil
60
+ rollback = false
59
61
  r = @fb.txn(this) do |fbt|
60
- tail = Factbase::Looged.elapsed do
61
- yield fbt
62
- end
62
+ id = fbt.object_id
63
+ yield fbt
63
64
  rescue Factbase::Rollback => e
64
- @loog.debug('Txn rolled back')
65
+ rollback = true
65
66
  raise e
66
67
  end
67
- @loog.debug("Txn #{r ? 'modified' : 'didn\'t touch'} #{before} facts #{tail}")
68
+ if rollback
69
+ @loog.debug("Txn ##{id} rolled back in #{start.ago}")
70
+ else
71
+ @loog.debug("Txn ##{id} #{r ? 'modified' : 'didn\'t touch'} #{before} facts in #{start.ago}")
72
+ end
68
73
  r
69
74
  end
70
75
 
@@ -24,18 +24,30 @@ require_relative '../factbase'
24
24
  require_relative '../factbase/syntax'
25
25
 
26
26
  # A decorator of a Factbase, that checks rules on every set.
27
+ #
28
+ # Say, you want every fact to have +foo+ property. You want any attempt
29
+ # to insert a fact without this property to lead to a runtime error. Here is how:
30
+ #
31
+ # fb = Factbase.new
32
+ # fb = Factabase::Rules.new(fb, '(exists foo)')
33
+ # fb.txn do |fbt|
34
+ # f = fbt.insert
35
+ # f.bar = 3
36
+ # end # Runtime exception here (transaction won't commit)
37
+ #
27
38
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
39
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
29
40
  # License:: MIT
30
41
  class Factbase::Rules
31
- def initialize(fb, rules, check = Check.new(rules))
42
+ def initialize(fb, rules, check = Check.new(rules), uid: nil)
32
43
  @fb = fb
33
44
  @rules = rules
34
45
  @check = check
46
+ @uid = uid
35
47
  end
36
48
 
37
49
  def dup
38
- Factbase::Rules.new(@fb.dup, @rules, @check)
50
+ Factbase::Rules.new(@fb.dup, @rules, @check, uid: @uid)
39
51
  end
40
52
 
41
53
  def size
@@ -52,15 +64,16 @@ class Factbase::Rules
52
64
 
53
65
  def txn(this = self, &)
54
66
  before = @check
55
- @check = Blind.new
56
- modified = @fb.txn(this, &)
57
- @check = before
58
- if modified
59
- @fb.query('(always)').each do |f|
67
+ later = Later.new(@uid)
68
+ @check = later
69
+ @fb.txn(this) do |fbt|
70
+ yield fbt
71
+ @check = before
72
+ fbt.query('(always)').each do |f|
73
+ next unless later.include?(f)
60
74
  @check.it(f)
61
75
  end
62
76
  end
63
- modified
64
77
  end
65
78
 
66
79
  def export
@@ -88,7 +101,7 @@ class Factbase::Rules
88
101
  def method_missing(*args)
89
102
  r = @fact.method_missing(*args)
90
103
  k = args[0].to_s
91
- @check.it(self) if k.end_with?('=')
104
+ @check.it(@fact) if k.end_with?('=')
92
105
  r
93
106
  end
94
107
 
@@ -143,9 +156,19 @@ class Factbase::Rules
143
156
  # Check one fact (never complaining).
144
157
  #
145
158
  # This is an internal class, it is not supposed to be instantiated directly.
146
- class Blind
147
- def it(_fact)
148
- true
159
+ class Later
160
+ def initialize(uid)
161
+ @uid = uid
162
+ @facts = Set.new
163
+ end
164
+
165
+ def it(fact)
166
+ @facts << fact.send(@uid) unless @uid.nil?
167
+ end
168
+
169
+ def include?(fact)
170
+ return true if @uid.nil?
171
+ @facts.include?(fact.send(@uid))
149
172
  end
150
173
  end
151
174
  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.49'
82
+ VERSION = '0.0.50'
83
83
 
84
84
  # An exception that may be thrown in a transaction, to roll it back.
85
85
  class Rollback < StandardError; end
@@ -63,6 +63,7 @@ class TestLooged < Minitest::Test
63
63
  assert(!fb.txn { raise Factbase::Rollback })
64
64
  assert_equal(0, fb.size)
65
65
  assert(log.to_s.include?('rolled back'), log)
66
+ assert(!log.to_s.include?('didn\'t touch'), log)
66
67
  end
67
68
 
68
69
  def test_with_modifying_txn
@@ -23,6 +23,7 @@
23
23
  require 'minitest/autorun'
24
24
  require_relative '../../lib/factbase'
25
25
  require_relative '../../lib/factbase/rules'
26
+ require_relative '../../lib/factbase/pre'
26
27
 
27
28
  # Test.
28
29
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -66,6 +67,18 @@ class TestRules < Minitest::Test
66
67
  assert(ok)
67
68
  end
68
69
 
70
+ def test_rollback_on_violation
71
+ fb = Factbase::Rules.new(Factbase.new, '(when (exists a) (exists b))')
72
+ assert_raises do
73
+ fb.txn do |fbt|
74
+ f = fbt.insert
75
+ f.a = 1
76
+ f.c = 2
77
+ end
78
+ end
79
+ assert_equal(0, fb.size)
80
+ end
81
+
69
82
  def test_in_combination_with_pre
70
83
  fb = Factbase::Rules.new(Factbase.new, '(when (exists a) (exists b))')
71
84
  fb = Factbase::Pre.new(fb) do |f|
@@ -81,6 +94,6 @@ class TestRules < Minitest::Test
81
94
  end
82
95
  end
83
96
  assert(ok)
84
- assert_equal(1, fb.query('(eq hello 42)').each.to_a.size)
97
+ assert_equal(0, fb.query('(eq hello 42)').each.to_a.size)
85
98
  end
86
99
  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.49
4
+ version: 0.0.50
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-11 00:00:00.000000000 Z
11
+ date: 2024-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json