factbase 0.0.24 → 0.0.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/.rultor.yml +2 -2
- data/factbase.gemspec +2 -1
- data/lib/factbase/fact.rb +1 -0
- data/lib/factbase/inv.rb +9 -14
- data/lib/factbase/looged.rb +9 -15
- data/lib/factbase/pre.rb +7 -14
- data/lib/factbase/query.rb +2 -2
- data/lib/factbase/rules.rb +124 -0
- data/lib/factbase/spy.rb +12 -4
- data/lib/factbase/syntax.rb +1 -0
- data/lib/factbase/term.rb +28 -7
- data/lib/factbase/to_json.rb +43 -0
- data/lib/factbase/to_xml.rb +75 -0
- data/lib/factbase/to_yaml.rb +43 -0
- data/lib/factbase.rb +22 -47
- data/test/factbase/test_inv.rb +2 -0
- data/test/factbase/test_looged.rb +1 -1
- data/test/factbase/test_pre.rb +1 -0
- data/test/factbase/test_query.rb +3 -0
- data/test/factbase/test_rules.rb +45 -0
- data/test/factbase/test_syntax.rb +2 -1
- data/test/factbase/test_term.rb +54 -35
- data/test/factbase/test_to_json.rb +42 -0
- data/test/factbase/test_to_xml.rb +75 -0
- data/test/factbase/test_to_yaml.rb +45 -0
- data/test/test_factbase.rb +62 -40
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1be768141fbb97e4753b38b4b8c438a8cf870957744868af05ab325bec94582c
|
4
|
+
data.tar.gz: bcef0970b79fba877d7f677440e595382a64cab724b00d7df101a0a2bf66d146
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b705bad3bc10f08a9865217f015069c34e679c6718382f321926d6ae76b96db6e56dd4c76540eeec8fb0511a8e7a40077d7ac8092fbe6588d75cefaf9e5f4d1
|
7
|
+
data.tar.gz: 3e4c1a563194008beb1697f5a4e146a0a88713fb876c8414893bff69db34b33a10d812135f85cac8ef9655d50d40d7186a3b00aa4c863f5ce4ba4a52429d9c37
|
data/.rubocop.yml
CHANGED
@@ -44,9 +44,13 @@ Metrics/CyclomaticComplexity:
|
|
44
44
|
Max: 20
|
45
45
|
Metrics/PerceivedComplexity:
|
46
46
|
Max: 20
|
47
|
+
Metrics/ClassLength:
|
48
|
+
Enabled: false
|
47
49
|
Layout/EmptyLineAfterGuardClause:
|
48
50
|
Enabled: false
|
49
51
|
Naming/MethodParameterName:
|
50
52
|
MinNameLength: 2
|
51
53
|
Layout/EndOfLine:
|
52
54
|
EnforcedStyle: lf
|
55
|
+
Security/MarshalLoad:
|
56
|
+
Enabled: false
|
data/.rultor.yml
CHANGED
@@ -31,8 +31,8 @@ release:
|
|
31
31
|
[[ "${tag}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || exit -1
|
32
32
|
bundle exec rake
|
33
33
|
rm -rf *.gem
|
34
|
-
sed -i "s/0\.0\.0/${tag}/g" factbase.
|
35
|
-
git add factbase.
|
34
|
+
sed -i "s/0\.0\.0/${tag}/g" lib/factbase.rb
|
35
|
+
git add lib/factbase.rb
|
36
36
|
git commit -m "version set to ${tag}"
|
37
37
|
gem build factbase.gemspec
|
38
38
|
chmod 0600 ../rubygems.yml
|
data/factbase.gemspec
CHANGED
@@ -21,12 +21,13 @@
|
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
23
|
require 'English'
|
24
|
+
require_relative 'lib/factbase'
|
24
25
|
|
25
26
|
Gem::Specification.new do |s|
|
26
27
|
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
|
27
28
|
s.required_ruby_version = '>=2.3'
|
28
29
|
s.name = 'factbase'
|
29
|
-
s.version =
|
30
|
+
s.version = Factbase::VERSION
|
30
31
|
s.license = 'MIT'
|
31
32
|
s.summary = 'Factbase'
|
32
33
|
s.description = 'Fact base in memory and on disc'
|
data/lib/factbase/fact.rb
CHANGED
@@ -46,6 +46,7 @@ class Factbase::Fact
|
|
46
46
|
if k.end_with?('=')
|
47
47
|
kk = k[0..-2]
|
48
48
|
raise "Invalid prop name '#{kk}'" unless kk.match?(/^[a-z][_a-zA-Z0-9]*$/)
|
49
|
+
raise "Prohibited prop name '#{kk}'" if kk == 'to_s'
|
49
50
|
v = args[1]
|
50
51
|
raise "Prop value can't be nil" if v.nil?
|
51
52
|
raise "Prop value can't be empty" if v == ''
|
data/lib/factbase/inv.rb
CHANGED
@@ -20,6 +20,8 @@
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
|
+
require_relative '../factbase'
|
24
|
+
|
23
25
|
# A decorator of a Factbase, that checks invariants on every set.
|
24
26
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
25
27
|
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
@@ -30,8 +32,8 @@ class Factbase::Inv
|
|
30
32
|
@block = block
|
31
33
|
end
|
32
34
|
|
33
|
-
def
|
34
|
-
@fb.
|
35
|
+
def dup
|
36
|
+
Factbase::Inv.new(@fb.dup, &@block)
|
35
37
|
end
|
36
38
|
|
37
39
|
def size
|
@@ -46,6 +48,10 @@ class Factbase::Inv
|
|
46
48
|
Query.new(@fb.query(query), @block)
|
47
49
|
end
|
48
50
|
|
51
|
+
def txn(this = self, &)
|
52
|
+
@fb.txn(this, &)
|
53
|
+
end
|
54
|
+
|
49
55
|
def export
|
50
56
|
@fb.export
|
51
57
|
end
|
@@ -54,18 +60,6 @@ class Factbase::Inv
|
|
54
60
|
@fb.import(bytes)
|
55
61
|
end
|
56
62
|
|
57
|
-
def to_json(opt = nil)
|
58
|
-
@fb.to_json(opt)
|
59
|
-
end
|
60
|
-
|
61
|
-
def to_xml
|
62
|
-
@fb.to_xml
|
63
|
-
end
|
64
|
-
|
65
|
-
def to_yaml
|
66
|
-
@fb.to_yaml
|
67
|
-
end
|
68
|
-
|
69
63
|
# Fact decorator.
|
70
64
|
class Fact
|
71
65
|
def initialize(fact, block)
|
@@ -102,6 +96,7 @@ class Factbase::Inv
|
|
102
96
|
end
|
103
97
|
|
104
98
|
def each
|
99
|
+
return to_enum(__method__) unless block_given?
|
105
100
|
@query.each do |f|
|
106
101
|
yield Fact.new(f, @block)
|
107
102
|
end
|
data/lib/factbase/looged.rb
CHANGED
@@ -32,8 +32,8 @@ class Factbase::Looged
|
|
32
32
|
@loog = loog
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
@fb.
|
35
|
+
def dup
|
36
|
+
Factbase::Looged.new(@fb.dup, @loog)
|
37
37
|
end
|
38
38
|
|
39
39
|
def size
|
@@ -50,6 +50,10 @@ class Factbase::Looged
|
|
50
50
|
Query.new(@fb.query(query), query, @loog)
|
51
51
|
end
|
52
52
|
|
53
|
+
def txn(this = self, &)
|
54
|
+
@fb.txn(this, &)
|
55
|
+
end
|
56
|
+
|
53
57
|
def export
|
54
58
|
@fb.export
|
55
59
|
end
|
@@ -58,18 +62,6 @@ class Factbase::Looged
|
|
58
62
|
@fb.import(bytes)
|
59
63
|
end
|
60
64
|
|
61
|
-
def to_json(opt = nil)
|
62
|
-
@fb.to_json(opt)
|
63
|
-
end
|
64
|
-
|
65
|
-
def to_xml
|
66
|
-
@fb.to_xml
|
67
|
-
end
|
68
|
-
|
69
|
-
def to_yaml
|
70
|
-
@fb.to_yaml
|
71
|
-
end
|
72
|
-
|
73
65
|
# Fact decorator.
|
74
66
|
class Fact
|
75
67
|
def initialize(fact, loog)
|
@@ -85,7 +77,9 @@ class Factbase::Looged
|
|
85
77
|
r = @fact.method_missing(*args)
|
86
78
|
k = args[0].to_s
|
87
79
|
v = args[1]
|
88
|
-
|
80
|
+
s = v.is_a?(Time) ? v.utc.iso8601 : v.to_s
|
81
|
+
s = v.to_s.inspect if v.is_a?(String)
|
82
|
+
@loog.debug("Set '#{k[0..-2]}' to #{s} (#{v.class})") if k.end_with?('=')
|
89
83
|
r
|
90
84
|
end
|
91
85
|
|
data/lib/factbase/pre.rb
CHANGED
@@ -21,6 +21,7 @@
|
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
23
|
require 'loog'
|
24
|
+
require_relative '../factbase'
|
24
25
|
|
25
26
|
# A decorator of a Factbase, that runs a provided block on every +insert+.
|
26
27
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -32,8 +33,8 @@ class Factbase::Pre
|
|
32
33
|
@block = block
|
33
34
|
end
|
34
35
|
|
35
|
-
def
|
36
|
-
@fb.
|
36
|
+
def dup
|
37
|
+
Factbase::Pre.new(@fb.dup, &@block)
|
37
38
|
end
|
38
39
|
|
39
40
|
def size
|
@@ -50,6 +51,10 @@ class Factbase::Pre
|
|
50
51
|
@fb.query(query)
|
51
52
|
end
|
52
53
|
|
54
|
+
def txn(this = self, &)
|
55
|
+
@fb.txn(this, &)
|
56
|
+
end
|
57
|
+
|
53
58
|
def export
|
54
59
|
@fb.export
|
55
60
|
end
|
@@ -57,16 +62,4 @@ class Factbase::Pre
|
|
57
62
|
def import(bytes)
|
58
63
|
@fb.import(bytes)
|
59
64
|
end
|
60
|
-
|
61
|
-
def to_json(opt = nil)
|
62
|
-
@fb.to_json(opt)
|
63
|
-
end
|
64
|
-
|
65
|
-
def to_xml
|
66
|
-
@fb.to_xml
|
67
|
-
end
|
68
|
-
|
69
|
-
def to_yaml
|
70
|
-
@fb.to_yaml
|
71
|
-
end
|
72
65
|
end
|
data/lib/factbase/query.rb
CHANGED
@@ -44,7 +44,7 @@ class Factbase::Query
|
|
44
44
|
yielded = 0
|
45
45
|
@maps.each do |m|
|
46
46
|
f = Factbase::Fact.new(@mutex, m)
|
47
|
-
next unless term.
|
47
|
+
next unless term.eval(f)
|
48
48
|
yield f
|
49
49
|
yielded += 1
|
50
50
|
end
|
@@ -59,7 +59,7 @@ class Factbase::Query
|
|
59
59
|
@mutex.synchronize do
|
60
60
|
@maps.delete_if do |m|
|
61
61
|
f = Factbase::Fact.new(@mutex, m)
|
62
|
-
if term.
|
62
|
+
if term.eval(f)
|
63
63
|
deleted += 1
|
64
64
|
true
|
65
65
|
else
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2024 Yegor Bugayenko
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require_relative '../factbase'
|
24
|
+
|
25
|
+
# A decorator of a Factbase, that checks rules on every set.
|
26
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
+
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
28
|
+
# License:: MIT
|
29
|
+
class Factbase::Rules
|
30
|
+
def initialize(fb, rules)
|
31
|
+
@fb = fb
|
32
|
+
@rules = rules
|
33
|
+
@check = Check.new(fb, @rules)
|
34
|
+
end
|
35
|
+
|
36
|
+
def dup
|
37
|
+
Factbase::Rules.new(@fb.dup, @rules)
|
38
|
+
end
|
39
|
+
|
40
|
+
def size
|
41
|
+
@fb.size
|
42
|
+
end
|
43
|
+
|
44
|
+
def insert
|
45
|
+
Fact.new(@fb.insert, @check)
|
46
|
+
end
|
47
|
+
|
48
|
+
def query(query)
|
49
|
+
Query.new(@fb.query(query), @check)
|
50
|
+
end
|
51
|
+
|
52
|
+
def txn(this = self, &)
|
53
|
+
@fb.txn(this, &)
|
54
|
+
end
|
55
|
+
|
56
|
+
def export
|
57
|
+
@fb.export
|
58
|
+
end
|
59
|
+
|
60
|
+
def import(bytes)
|
61
|
+
@fb.import(bytes)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Fact decorator.
|
65
|
+
class Fact
|
66
|
+
def initialize(fact, check)
|
67
|
+
@fact = fact
|
68
|
+
@check = check
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
@fact.to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
def method_missing(*args)
|
76
|
+
r = @fact.method_missing(*args)
|
77
|
+
k = args[0].to_s
|
78
|
+
@check.it(self) if k.end_with?('=')
|
79
|
+
r
|
80
|
+
end
|
81
|
+
|
82
|
+
# rubocop:disable Style/OptionalBooleanParameter
|
83
|
+
def respond_to?(method, include_private = false)
|
84
|
+
# rubocop:enable Style/OptionalBooleanParameter
|
85
|
+
@fact.respond_to?(method, include_private)
|
86
|
+
end
|
87
|
+
|
88
|
+
def respond_to_missing?(method, include_private = false)
|
89
|
+
@fact.respond_to_missing?(method, include_private)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Query decorator.
|
94
|
+
class Query
|
95
|
+
def initialize(query, check)
|
96
|
+
@query = query
|
97
|
+
@check = check
|
98
|
+
end
|
99
|
+
|
100
|
+
def each
|
101
|
+
return to_enum(__method__) unless block_given?
|
102
|
+
@query.each do |f|
|
103
|
+
yield Fact.new(f, @check)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def delete!
|
108
|
+
@query.delete!
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Check one fact.
|
113
|
+
class Check
|
114
|
+
def initialize(fb, expr)
|
115
|
+
@fb = fb
|
116
|
+
@expr = expr
|
117
|
+
end
|
118
|
+
|
119
|
+
def it(fact)
|
120
|
+
return if Factbase::Syntax.new(@expr).to_term.eval(fact)
|
121
|
+
raise "The fact is in invalid state: #{fact}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
data/lib/factbase/spy.rb
CHANGED
@@ -37,6 +37,14 @@ class Factbase::Spy
|
|
37
37
|
@caught
|
38
38
|
end
|
39
39
|
|
40
|
+
def dup
|
41
|
+
Factbase::Spy.new(@fb.dup, @key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def size
|
45
|
+
@fb.size
|
46
|
+
end
|
47
|
+
|
40
48
|
def query(expr)
|
41
49
|
scan(Factbase::Syntax.new(expr).to_term)
|
42
50
|
@fb.query(expr)
|
@@ -50,12 +58,12 @@ class Factbase::Spy
|
|
50
58
|
@fb.export
|
51
59
|
end
|
52
60
|
|
53
|
-
def
|
54
|
-
@fb.
|
61
|
+
def txn(this = self, &)
|
62
|
+
@fb.txn(this, &)
|
55
63
|
end
|
56
64
|
|
57
|
-
def
|
58
|
-
@fb.
|
65
|
+
def import(data)
|
66
|
+
@fb.import(data)
|
59
67
|
end
|
60
68
|
|
61
69
|
# A fact that is spying.
|
data/lib/factbase/syntax.rb
CHANGED
data/lib/factbase/term.rb
CHANGED
@@ -41,7 +41,7 @@ class Factbase::Term
|
|
41
41
|
# Does it match the fact?
|
42
42
|
# @param [Factbase::Fact] fact The fact
|
43
43
|
# @return [bool] TRUE if matches
|
44
|
-
def
|
44
|
+
def eval(fact)
|
45
45
|
send(@op, fact)
|
46
46
|
end
|
47
47
|
|
@@ -71,23 +71,30 @@ class Factbase::Term
|
|
71
71
|
|
72
72
|
def not(fact)
|
73
73
|
assert_args(1)
|
74
|
-
!@operands[0].
|
74
|
+
!@operands[0].eval(fact)
|
75
75
|
end
|
76
76
|
|
77
77
|
def or(fact)
|
78
78
|
@operands.each do |o|
|
79
|
-
return true if o.
|
79
|
+
return true if o.eval(fact)
|
80
80
|
end
|
81
81
|
false
|
82
82
|
end
|
83
83
|
|
84
84
|
def and(fact)
|
85
85
|
@operands.each do |o|
|
86
|
-
return false unless o.
|
86
|
+
return false unless o.eval(fact)
|
87
87
|
end
|
88
88
|
true
|
89
89
|
end
|
90
90
|
|
91
|
+
def when(fact)
|
92
|
+
assert_args(2)
|
93
|
+
a = @operands[0]
|
94
|
+
b = @operands[1]
|
95
|
+
!a.eval(fact) || (a.eval(fact) && b.eval(fact))
|
96
|
+
end
|
97
|
+
|
91
98
|
def exists(fact)
|
92
99
|
assert_args(1)
|
93
100
|
o = @operands[0]
|
@@ -116,12 +123,26 @@ class Factbase::Term
|
|
116
123
|
arithmetic(:>, fact)
|
117
124
|
end
|
118
125
|
|
126
|
+
def size(fact)
|
127
|
+
assert_args(1)
|
128
|
+
o = @operands[0]
|
129
|
+
raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
|
130
|
+
k = o.to_s
|
131
|
+
return 0 if fact[k].nil?
|
132
|
+
return 1 unless fact[k].is_a?(Array)
|
133
|
+
fact[k].size
|
134
|
+
end
|
135
|
+
|
119
136
|
def arithmetic(op, fact)
|
120
137
|
assert_args(2)
|
121
138
|
o = @operands[0]
|
122
|
-
|
123
|
-
|
124
|
-
|
139
|
+
if o.is_a?(Factbase::Term)
|
140
|
+
v = o.eval(fact)
|
141
|
+
else
|
142
|
+
raise "A symbol expected by #{op}: #{o}" unless o.is_a?(Symbol)
|
143
|
+
k = o.to_s
|
144
|
+
v = fact[k]
|
145
|
+
end
|
125
146
|
return false if v.nil?
|
126
147
|
v = [v] unless v.is_a?(Array)
|
127
148
|
v.any? do |vv|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2024 Yegor Bugayenko
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require 'json'
|
24
|
+
require 'time'
|
25
|
+
require_relative '../factbase'
|
26
|
+
|
27
|
+
# Factbase to JSON converter.
|
28
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
+
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
30
|
+
# License:: MIT
|
31
|
+
class Factbase::ToJSON
|
32
|
+
# Constructor.
|
33
|
+
def initialize(fb)
|
34
|
+
@fb = fb
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert the entire factbase into JSON.
|
38
|
+
# @return [String] The factbase in JSON format
|
39
|
+
def json
|
40
|
+
maps = Marshal.load(@fb.export)
|
41
|
+
maps.to_json
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2024 Yegor Bugayenko
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require 'nokogiri'
|
24
|
+
require 'time'
|
25
|
+
require_relative '../factbase'
|
26
|
+
|
27
|
+
# Factbase to XML converter.
|
28
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
+
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
30
|
+
# License:: MIT
|
31
|
+
class Factbase::ToXML
|
32
|
+
# Constructor.
|
33
|
+
def initialize(fb)
|
34
|
+
@fb = fb
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert the entire factbase into XML.
|
38
|
+
# @return [String] The factbase in XML format
|
39
|
+
def xml
|
40
|
+
meta = {
|
41
|
+
factbase_version: Factbase::VERSION,
|
42
|
+
dob: Time.now.utc.iso8601
|
43
|
+
}
|
44
|
+
maps = Marshal.load(@fb.export)
|
45
|
+
Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
46
|
+
xml.fb(meta) do
|
47
|
+
maps.each do |m|
|
48
|
+
xml.f_ do
|
49
|
+
m.each do |k, vv|
|
50
|
+
if vv.is_a?(Array)
|
51
|
+
xml.send(:"#{k}_") do
|
52
|
+
vv.each do |v|
|
53
|
+
xml.send(:v, to_str(v))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
else
|
57
|
+
xml.send(:"#{k}_", to_str(vv))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end.to_xml
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def to_str(val)
|
69
|
+
if val.is_a?(Time)
|
70
|
+
val.utc.iso8601
|
71
|
+
else
|
72
|
+
val.to_s
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2024 Yegor Bugayenko
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require 'yaml'
|
24
|
+
require 'time'
|
25
|
+
require_relative '../factbase'
|
26
|
+
|
27
|
+
# Factbase to YAML converter.
|
28
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
+
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
30
|
+
# License:: MIT
|
31
|
+
class Factbase::ToYAML
|
32
|
+
# Constructor.
|
33
|
+
def initialize(fb)
|
34
|
+
@fb = fb
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert the entire factbase into YAML.
|
38
|
+
# @return [String] The factbase in YAML format
|
39
|
+
def yaml
|
40
|
+
maps = Marshal.load(@fb.export)
|
41
|
+
YAML.dump({ 'facts' => maps })
|
42
|
+
end
|
43
|
+
end
|