factbase 0.0.17 → 0.0.18
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/.github/workflows/rake.yml +1 -1
- data/README.md +4 -3
- data/factbase.gemspec +1 -1
- data/lib/factbase/fact.rb +1 -0
- data/lib/factbase/looged.rb +14 -3
- data/lib/factbase/term.rb +9 -3
- data/test/factbase/test_fact.rb +8 -0
- data/test/factbase/test_term.rb +11 -11
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0ff9bc1f66c58988b0a6758b11694dc5cbcc0b7c004f862ec00fd075b599ec1
|
4
|
+
data.tar.gz: 9c75cc130b0b641cbcf67bab0f11cc0b794a68e6449fb0c3e1fac38b337194e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eaa74d8e6c7f30a4f743aa69b51186803bfeb6959b1e9e2f8a929e7ad8813aeff3bc2beb4431157440bd8af5991bf163390fceb3ba2cb200b5167901aa2521f9
|
7
|
+
data.tar.gz: cb79dff273324c4292187f048ed1f7ec8e9559ad391242c071e5e097141e6b7bb42f501fc684e01f4c5adb4fc30ade033115719acbeb4393cd9465765ff246d9
|
data/.github/workflows/rake.yml
CHANGED
data/README.md
CHANGED
@@ -32,11 +32,12 @@ end
|
|
32
32
|
You can save the factbase to disc and load it back:
|
33
33
|
|
34
34
|
```ruby
|
35
|
+
file = '/tmp/simple.fb'
|
35
36
|
f1 = Factbase.new
|
36
37
|
f1.insert
|
37
|
-
File.save(
|
38
|
+
File.save(file, f1.export)
|
38
39
|
f2 = Factbase.new
|
39
|
-
f2.import(File.read(
|
40
|
+
f2.import(File.read(file))
|
40
41
|
```
|
41
42
|
|
42
43
|
## How to contribute
|
@@ -44,7 +45,7 @@ f2.import(File.read('/tmp/db.txt'))
|
|
44
45
|
Read [these guidelines](https://www.yegor256.com/2014/04/15/github-guidelines.html).
|
45
46
|
Make sure you build is green before you contribute
|
46
47
|
your pull request. You will need to have
|
47
|
-
[Ruby](https://www.ruby-lang.org/en/) 2
|
48
|
+
[Ruby](https://www.ruby-lang.org/en/) 3.2+ and
|
48
49
|
[Bundler](https://bundler.io/) installed. Then:
|
49
50
|
|
50
51
|
```bash
|
data/factbase.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
|
27
27
|
s.required_ruby_version = '>=2.3'
|
28
28
|
s.name = 'factbase'
|
29
|
-
s.version = '0.0.
|
29
|
+
s.version = '0.0.18'
|
30
30
|
s.license = 'MIT'
|
31
31
|
s.summary = 'Factbase'
|
32
32
|
s.description = 'Fact base in memory and on disc'
|
data/lib/factbase/fact.rb
CHANGED
@@ -46,6 +46,7 @@ class Factbase::Fact
|
|
46
46
|
raise "Prop value can't be nil" if v.nil?
|
47
47
|
raise "Prop value can't be empty" if v == ''
|
48
48
|
raise "Prop type '#{v.class}' is not allowed" unless [String, Integer, Float, Time].include?(v.class)
|
49
|
+
v = v.utc if v.is_a?(Time)
|
49
50
|
@mutex.synchronize do
|
50
51
|
before = @map[kk]
|
51
52
|
return if before == v
|
data/lib/factbase/looged.rb
CHANGED
@@ -84,7 +84,8 @@ class Factbase::Looged
|
|
84
84
|
def method_missing(*args)
|
85
85
|
r = @fact.method_missing(*args)
|
86
86
|
k = args[0].to_s
|
87
|
-
|
87
|
+
v = args[1]
|
88
|
+
@loog.debug("Set '#{k[0..-2]}' to '#{v.to_s.inspect}' (#{v.class})") if k.end_with?('=')
|
88
89
|
r
|
89
90
|
end
|
90
91
|
|
@@ -109,13 +110,23 @@ class Factbase::Looged
|
|
109
110
|
|
110
111
|
def each(&)
|
111
112
|
r = @query.each(&)
|
112
|
-
|
113
|
+
c = r.size
|
114
|
+
if c.zero?
|
115
|
+
@loog.debug("Nothing found by '#{@expr}'")
|
116
|
+
else
|
117
|
+
@loog.debug("Found #{c} facts by '#{@expr}'")
|
118
|
+
end
|
113
119
|
r
|
114
120
|
end
|
115
121
|
|
116
122
|
def delete!
|
117
123
|
r = @query.delete!
|
118
|
-
|
124
|
+
c = r.size
|
125
|
+
if c.zero?
|
126
|
+
@loog.debug("Nothing deleted by '#{@expr}'")
|
127
|
+
else
|
128
|
+
@loog.debug("Deleted #{r.size} facts by '#{@expr}'")
|
129
|
+
end
|
119
130
|
r
|
120
131
|
end
|
121
132
|
end
|
data/lib/factbase/term.rb
CHANGED
@@ -85,13 +85,17 @@ class Factbase::Term
|
|
85
85
|
|
86
86
|
def exists(fact)
|
87
87
|
assert_args(1)
|
88
|
-
|
88
|
+
o = @operands[0]
|
89
|
+
raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
|
90
|
+
k = o.to_s
|
89
91
|
!fact[k].nil?
|
90
92
|
end
|
91
93
|
|
92
94
|
def absent(fact)
|
93
95
|
assert_args(1)
|
94
|
-
|
96
|
+
o = @operands[0]
|
97
|
+
raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
|
98
|
+
k = o.to_s
|
95
99
|
fact[k].nil?
|
96
100
|
end
|
97
101
|
|
@@ -109,7 +113,9 @@ class Factbase::Term
|
|
109
113
|
|
110
114
|
def arithmetic(op, fact)
|
111
115
|
assert_args(2)
|
112
|
-
|
116
|
+
o = @operands[0]
|
117
|
+
raise "A symbol expected by #{op}: #{o}" unless o.is_a?(Symbol)
|
118
|
+
k = o.to_s
|
113
119
|
v = fact[k]
|
114
120
|
return false if v.nil?
|
115
121
|
v = [v] unless v.is_a?(Array)
|
data/test/factbase/test_fact.rb
CHANGED
@@ -73,4 +73,12 @@ class TestFact < Minitest::Test
|
|
73
73
|
f.send('foo_bar=', 42)
|
74
74
|
assert_equal(42, f.foo_bar, f.to_s)
|
75
75
|
end
|
76
|
+
|
77
|
+
def test_time_in_utc
|
78
|
+
f = Factbase::Fact.new(Mutex.new, {})
|
79
|
+
t = Time.now
|
80
|
+
f.foo = t
|
81
|
+
assert_equal(t.utc, f.foo)
|
82
|
+
assert_equal(t.utc.to_s, f.foo.to_s)
|
83
|
+
end
|
76
84
|
end
|
data/test/factbase/test_term.rb
CHANGED
@@ -29,14 +29,14 @@ require_relative '../../lib/factbase/term'
|
|
29
29
|
# License:: MIT
|
30
30
|
class TestTerm < Minitest::Test
|
31
31
|
def test_simple_matching
|
32
|
-
t = Factbase::Term.new(:eq, [
|
32
|
+
t = Factbase::Term.new(:eq, [:foo, 42])
|
33
33
|
assert(t.matches?(fact('foo' => [42])))
|
34
34
|
assert(!t.matches?(fact('foo' => 'Hello!')))
|
35
35
|
assert(!t.matches?(fact('bar' => ['Hello!'])))
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_eq_matching
|
39
|
-
t = Factbase::Term.new(:eq, [
|
39
|
+
t = Factbase::Term.new(:eq, [:foo, 42])
|
40
40
|
assert(t.matches?(fact('foo' => 42)))
|
41
41
|
assert(t.matches?(fact('foo' => [10, 5, 6, -8, 'hey', 42, 9, 'fdsf'])))
|
42
42
|
assert(!t.matches?(fact('foo' => [100])))
|
@@ -45,7 +45,7 @@ class TestTerm < Minitest::Test
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_lt_matching
|
48
|
-
t = Factbase::Term.new(:lt, [
|
48
|
+
t = Factbase::Term.new(:lt, [:foo, 42])
|
49
49
|
assert(t.matches?(fact('foo' => [10])))
|
50
50
|
assert(!t.matches?(fact('foo' => [100])))
|
51
51
|
assert(!t.matches?(fact('foo' => 100)))
|
@@ -53,7 +53,7 @@ class TestTerm < Minitest::Test
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def test_gt_matching
|
56
|
-
t = Factbase::Term.new(:gt, [
|
56
|
+
t = Factbase::Term.new(:gt, [:foo, 42])
|
57
57
|
assert(t.matches?(fact('foo' => [100])))
|
58
58
|
assert(t.matches?(fact('foo' => 100)))
|
59
59
|
assert(!t.matches?(fact('foo' => [10])))
|
@@ -62,14 +62,14 @@ class TestTerm < Minitest::Test
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def test_lt_matching_time
|
65
|
-
t = Factbase::Term.new(:lt, [
|
65
|
+
t = Factbase::Term.new(:lt, [:foo, Time.now])
|
66
66
|
assert(t.matches?(fact('foo' => [Time.now - 100])))
|
67
67
|
assert(!t.matches?(fact('foo' => [Time.now + 100])))
|
68
68
|
assert(!t.matches?(fact('bar' => [100])))
|
69
69
|
end
|
70
70
|
|
71
71
|
def test_gt_matching_time
|
72
|
-
t = Factbase::Term.new(:gt, [
|
72
|
+
t = Factbase::Term.new(:gt, [:foo, Time.now])
|
73
73
|
assert(t.matches?(fact('foo' => [Time.now + 100])))
|
74
74
|
assert(!t.matches?(fact('foo' => [Time.now - 100])))
|
75
75
|
assert(!t.matches?(fact('bar' => [100])))
|
@@ -81,19 +81,19 @@ class TestTerm < Minitest::Test
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def test_not_eq_matching
|
84
|
-
t = Factbase::Term.new(:not, [Factbase::Term.new(:eq, [
|
84
|
+
t = Factbase::Term.new(:not, [Factbase::Term.new(:eq, [:foo, 100])])
|
85
85
|
assert(t.matches?(fact('foo' => [42, 12, -90])))
|
86
86
|
assert(!t.matches?(fact('foo' => 100)))
|
87
87
|
end
|
88
88
|
|
89
89
|
def test_exists_matching
|
90
|
-
t = Factbase::Term.new(:exists, [
|
90
|
+
t = Factbase::Term.new(:exists, [:foo])
|
91
91
|
assert(t.matches?(fact('foo' => [42, 12, -90])))
|
92
92
|
assert(!t.matches?(fact('bar' => 100)))
|
93
93
|
end
|
94
94
|
|
95
95
|
def test_absent_matching
|
96
|
-
t = Factbase::Term.new(:absent, [
|
96
|
+
t = Factbase::Term.new(:absent, [:foo])
|
97
97
|
assert(t.matches?(fact('z' => [42, 12, -90])))
|
98
98
|
assert(!t.matches?(fact('foo' => 100)))
|
99
99
|
end
|
@@ -102,8 +102,8 @@ class TestTerm < Minitest::Test
|
|
102
102
|
t = Factbase::Term.new(
|
103
103
|
:or,
|
104
104
|
[
|
105
|
-
Factbase::Term.new(:eq, [
|
106
|
-
Factbase::Term.new(:eq, [
|
105
|
+
Factbase::Term.new(:eq, [:foo, 4]),
|
106
|
+
Factbase::Term.new(:eq, [:bar, 5])
|
107
107
|
]
|
108
108
|
)
|
109
109
|
assert(t.matches?(fact('foo' => [4])))
|