factbase 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 973358a29608045c0279b7c0840607a325d90f3d5dc77c90c733d1f3936723d4
4
- data.tar.gz: 49e0510527f0cb13bb8b5ea11528392897173ee665343c71bc6e368c32a75d35
3
+ metadata.gz: 9b1ded0d5a1d5775620d8515eee9ad93ca71c97b70d68bd8624ca5bd55b112b0
4
+ data.tar.gz: fe93a4e058eb22a5e4db9c4c70a24461a8c790794df7f9a787989eb07b48837d
5
5
  SHA512:
6
- metadata.gz: 47b1925a557068e94a59f6f7638a5196a5802a8df1ecfb99fb8fe87b40e2efda43c88c6939acf0851efde6c1f491e55d63175c7680cd96853f9390e52b1a90ee
7
- data.tar.gz: 61d88a0052bdd2c8ecdc7bad27a1161b481433cae0e7ad1cf32813a7842dc9e6db5ff8f6b7553a55e9abd93b9a9ac124c275bd639451a34c8a4491ca98b753c8
6
+ metadata.gz: 8849f7c00995c3e202c648f4435821825ad5dc79074d2312885b2aa56ceb9a90bffffc3fb4ca7c7292fbeefb34da75a99baf59d32f3a0e421ea461d745fcc8db
7
+ data.tar.gz: 0d0cd7b0234b6de46e2a32d9e6c6c45f579e4bb5a09dbb99407d5844a4f206fa0b92977ae921daa6a691a5a4c7dde25f0f90300f4e99c09e7d4107570eb0e7c6
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.13'
29
+ s.version = '0.0.14'
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
@@ -43,7 +43,9 @@ class Factbase::Fact
43
43
  kk = k[0..-2]
44
44
  raise "Invalid prop name '#{kk}'" unless kk.match?(/^[a-z][_a-zA-Z0-9]*$/)
45
45
  v = args[1]
46
+ raise "Prop value can't be nil" if v.nil?
46
47
  raise "Prop value can't be empty" if v == ''
48
+ raise "Prop type '#{v.class}' is not allowed" unless [String, Integer, Float, Time].include?(v.class)
47
49
  @mutex.synchronize do
48
50
  before = @map[kk]
49
51
  return if before == v
@@ -37,12 +37,36 @@ class Factbase::Query
37
37
 
38
38
  # Iterate them one by one.
39
39
  # @yield [Fact] Facts one-by-one
40
+ # @return [Integer] Total number of facts yielded
40
41
  def each
42
+ return to_enum(__method__) unless block_given?
41
43
  term = Factbase::Syntax.new(@query).to_term
44
+ yielded = 0
42
45
  @maps.each do |m|
43
46
  f = Factbase::Fact.new(@mutex, m)
44
47
  next unless term.matches?(f)
45
48
  yield f
49
+ yielded += 1
46
50
  end
51
+ yielded
52
+ end
53
+
54
+ # Delete all facts that match the query.
55
+ # @return [Integer] Total number of facts deleted
56
+ def delete!
57
+ term = Factbase::Syntax.new(@query).to_term
58
+ deleted = 0
59
+ @mutex.synchronize do
60
+ @maps.delete_if do |m|
61
+ f = Factbase::Fact.new(@mutex, m)
62
+ if term.matches?(f)
63
+ deleted += 1
64
+ true
65
+ else
66
+ false
67
+ end
68
+ end
69
+ end
70
+ deleted
47
71
  end
48
72
  end
@@ -114,6 +114,10 @@ class Factbase::Syntax
114
114
  t[1..-2]
115
115
  elsif t.match?(/^[0-9]+$/)
116
116
  t.to_i
117
+ elsif t.match?(/^[0-9]+\.[0-9]+(e\+[0-9]+)?$/)
118
+ t.to_f
119
+ elsif t.match?(/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$/)
120
+ Time.parse(t)
117
121
  else
118
122
  t.to_sym
119
123
  end
data/lib/factbase/term.rb CHANGED
@@ -48,6 +48,8 @@ class Factbase::Term
48
48
  items += @operands.map do |o|
49
49
  if o.is_a?(String)
50
50
  "'#{o.gsub("'", "\\\\'").gsub('"', '\\\\"')}'"
51
+ elsif o.is_a?(Time)
52
+ o.utc.iso8601
51
53
  else
52
54
  o.to_s
53
55
  end
@@ -46,6 +46,20 @@ class TestFact < Minitest::Test
46
46
  end
47
47
  end
48
48
 
49
+ def test_fails_when_setting_nil
50
+ f = Factbase::Fact.new(Mutex.new, {})
51
+ assert_raises do
52
+ f.foo = nil
53
+ end
54
+ end
55
+
56
+ def test_fails_when_setting_empty
57
+ f = Factbase::Fact.new(Mutex.new, {})
58
+ assert_raises do
59
+ f.foo = ''
60
+ end
61
+ end
62
+
49
63
  def test_fails_when_not_found
50
64
  f = Factbase::Fact.new(Mutex.new, {})
51
65
  f.first = 42
@@ -33,8 +33,27 @@ class TestQuery < Minitest::Test
33
33
  maps = []
34
34
  maps << { 'foo' => [42] }
35
35
  q = Factbase::Query.new(maps, Mutex.new, '(eq foo 42)')
36
- q.each do |f|
37
- assert_equal(42, f.foo)
38
- end
36
+ assert_equal(
37
+ 1,
38
+ q.each do |f|
39
+ assert_equal(42, f.foo)
40
+ end
41
+ )
42
+ end
43
+
44
+ def test_simple_deleting
45
+ maps = []
46
+ maps << { 'foo' => [42] }
47
+ maps << { 'bar' => [4, 5] }
48
+ maps << { 'bar' => [5] }
49
+ q = Factbase::Query.new(maps, Mutex.new, '(eq bar 5)')
50
+ assert_equal(2, q.delete!)
51
+ assert_equal(1, maps.size)
52
+ end
53
+
54
+ def test_to_array
55
+ maps = []
56
+ maps << { 'foo' => [42] }
57
+ assert_equal(1, Factbase::Query.new(maps, Mutex.new, '(eq foo 42)').each.to_a.size)
39
58
  end
40
59
  end
@@ -61,6 +61,9 @@ class TestSyntax < Minitest::Test
61
61
  '(foo x y z)',
62
62
  "(foo x y z t f 42 'Hi!' 33)",
63
63
  '(foo (x) y z)',
64
+ '(eq t 2024-05-25T19:43:48Z)',
65
+ '(eq t 3.1415926)',
66
+ '(eq t 3.0e+21)',
64
67
  "(foo (x (f (t (y 42 'Hey you'))) (f) (r 3)) y z)"
65
68
  ].each do |q|
66
69
  assert_equal(q, Factbase::Syntax.new(q).to_term.to_s)
@@ -54,7 +54,7 @@ class TestFactbase < Minitest::Test
54
54
  File.write(f.path, f1.export)
55
55
  f2.import(File.read(f.path))
56
56
  end
57
- assert_equal(1, f2.query('(eq foo 42)').extend(Enumerable).to_a.count)
57
+ assert_equal(1, f2.query('(eq foo 42)').each.to_a.count)
58
58
  end
59
59
 
60
60
  def test_to_json
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.13
4
+ version: 0.0.14
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-05-13 00:00:00.000000000 Z
11
+ date: 2024-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json