bmg 0.4.1 → 0.5.0

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
  SHA1:
3
- metadata.gz: 7b43a1cda1c1650f7678db8e4a9213e7065d26a5
4
- data.tar.gz: 6f130fa599d6d24b4eaa0450883cfef539b95e6f
3
+ metadata.gz: 381472a4bb34f2a614c0520261508fb2c6ff6032
4
+ data.tar.gz: 562ca2c457720e0b7a12a5e9b9ccd33e1609b778
5
5
  SHA512:
6
- metadata.gz: 0ac9c79f0c348dbd7685a5c922a28a315192a72ce6b42da708b3233f1fb53da1b64da97659ddb3935aad39a4bdf3141d06be24ff102d202be0e7d8677fbb9f8a
7
- data.tar.gz: 40aea311e6e4d372ca07ffd91fd5c6ad102f3dd67da5443287121233848e3470ccded49eea97ef4e1f9d4a01afebeb4b43425e7426081ee2472cb0b8a95833ed
6
+ metadata.gz: 195468c7f66d2aa11d49678effe9dc5122e67aec2fbe3161549f6a351835a11f8957aaca4004143bc00256c121d4638c68d466f6267623d35ac5288855e5d7df
7
+ data.tar.gz: 1590b7723bec6a826e88a0eef3e1e659c80c355f41de3d61c5d31d4a6c872398f6698290ac464ea795e8bd67e1e5a4eebaaa4052468e61933a6a36b79df81db7
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
1
  source "https://rubygems.org"
2
2
  gemspec
3
+
4
+ gem 'predicate', path: '../predicate'
data/lib/bmg.rb CHANGED
@@ -15,6 +15,7 @@ module Bmg
15
15
  end
16
16
  require_relative 'bmg/version'
17
17
  require_relative 'bmg/error'
18
+ require_relative 'bmg/support'
18
19
  require_relative 'bmg/algebra'
19
20
  require_relative 'bmg/type'
20
21
  require_relative 'bmg/relation'
@@ -6,4 +6,7 @@ module Bmg
6
6
  # Raised by Relation#one when the relation is not a singleton
7
7
  class OneError < Error; end
8
8
 
9
+ # Raised when an update is invalid for some reason
10
+ class InvalidUpdateError < Error; end
11
+
9
12
  end
@@ -41,6 +41,23 @@ module Bmg
41
41
  end
42
42
  end
43
43
 
44
+ def insert(arg)
45
+ case arg
46
+ when Hash then operand.insert(valid_tuple!(arg))
47
+ when Enumerable then operand.insert(arg.map{|t| valid_tuple!(t) })
48
+ else
49
+ super
50
+ end
51
+ end
52
+
53
+ def update(tuple)
54
+ operand.update(valid_tuple!(tuple))
55
+ end
56
+
57
+ def delete
58
+ operand.delete
59
+ end
60
+
44
61
  def to_ast
45
62
  [:allbut, operand.to_ast, butlist.dup]
46
63
  end
@@ -54,7 +71,13 @@ module Bmg
54
71
  private
55
72
 
56
73
  def tuple_allbut(tuple)
57
- tuple.delete_if{|k,_| @butlist.include?(k) }
74
+ TupleAlgebra.allbut(tuple, @butlist)
75
+ end
76
+
77
+ def valid_tuple!(tuple)
78
+ offending = tuple.keys & butlist
79
+ raise InvalidUpdateError, "#{offending.inspect} cannot be updated" unless offending.empty?
80
+ tuple
58
81
  end
59
82
 
60
83
  end # class Allbut
@@ -42,6 +42,21 @@ module Bmg
42
42
  [:autosummarize, operand.to_ast, by.dup, sums.dup]
43
43
  end
44
44
 
45
+ protected
46
+
47
+ def _restrict(type, predicate)
48
+ top, bottom = predicate.and_split(sums.keys)
49
+ if top == predicate
50
+ super
51
+ else
52
+ op = operand
53
+ op = op.restrict(bottom)
54
+ op = op.autosummarize(by, sums)
55
+ op = op.restrict(top)
56
+ op
57
+ end
58
+ end
59
+
45
60
  private
46
61
 
47
62
  # Returns the tuple determinant.
@@ -29,6 +29,28 @@ module Bmg
29
29
  end
30
30
  end
31
31
 
32
+ def insert(arg)
33
+ case arg
34
+ when Hash then operand.insert(allbut_constants(arg))
35
+ when Relation then operand.insert(arg.allbut(constants.keys))
36
+ when Enumerable then operand.insert(arg.map{|t| allbut_constants(t) })
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ def update(tuple)
43
+ shared = tuple.keys & constants.keys
44
+ on_tuple = TupleAlgebra.project(tuple, shared)
45
+ on_const = TupleAlgebra.project(constants, shared)
46
+ raise InvalidUpdateError, "Cannot violate relvar predicate" unless on_tuple == on_const
47
+ operand.update(allbut_constants(tuple))
48
+ end
49
+
50
+ def delete
51
+ operand.delete
52
+ end
53
+
32
54
  def to_ast
33
55
  [ :constants, operand.to_ast, constants.dup ]
34
56
  end
@@ -78,6 +100,10 @@ module Bmg
78
100
  tuple.merge(@constants)
79
101
  end
80
102
 
103
+ def allbut_constants(tuple)
104
+ TupleAlgebra.allbut(tuple, constants.keys)
105
+ end
106
+
81
107
  end # class Constants
82
108
  end # module Operator
83
109
  end # module Bmg
@@ -32,10 +32,43 @@ module Bmg
32
32
  end
33
33
  end
34
34
 
35
+ def insert(arg)
36
+ case arg
37
+ when Hash then operand.insert(allbut_extkeys(arg))
38
+ when Relation then operand.insert(arg.allbut(extension.keys))
39
+ when Enumerable then operand.insert(arg.map{|t| allbut_extkeys(t) })
40
+ else
41
+ super
42
+ end
43
+ end
44
+
45
+ def update(tuple)
46
+ operand.update(allbut_extkeys(tuple))
47
+ end
48
+
49
+ def delete
50
+ operand.delete
51
+ end
52
+
35
53
  def to_ast
36
54
  [ :extend, operand.to_ast, extension.dup ]
37
55
  end
38
56
 
57
+ protected ### optimization
58
+
59
+ def _restrict(type, predicate)
60
+ top, bottom = predicate.and_split(extension.keys)
61
+ if top == predicate
62
+ super
63
+ else
64
+ op = operand
65
+ op = op.restrict(bottom)
66
+ op = op.extend(extension)
67
+ op = op.restrict(top)
68
+ op
69
+ end
70
+ end
71
+
39
72
  private
40
73
 
41
74
  def extend_it(tuple)
@@ -45,6 +78,10 @@ module Bmg
45
78
  }
46
79
  end
47
80
 
81
+ def allbut_extkeys(tuple)
82
+ TupleAlgebra.allbut(tuple, extension.keys)
83
+ end
84
+
48
85
  end # class Extend
49
86
  end # module Operator
50
87
  end # module Bmg
@@ -96,11 +96,11 @@ module Bmg
96
96
  private
97
97
 
98
98
  def tuple_project(tuple, on)
99
- on.each_with_object({}){|k,t| t[k] = tuple[k] }
99
+ TupleAlgebra.project(tuple, on)
100
100
  end
101
101
 
102
102
  def tuple_image(tuple, on)
103
- tuple.dup.delete_if{|k,_| on.include?(k) }
103
+ TupleAlgebra.allbut(tuple, on)
104
104
  end
105
105
 
106
106
  def image_type
@@ -40,6 +40,23 @@ module Bmg
40
40
  end
41
41
  end
42
42
 
43
+ def insert(arg)
44
+ case arg
45
+ when Hash then operand.insert(valid_tuple!(arg))
46
+ when Enumerable then operand.insert(arg.map{|t| valid_tuple!(t) })
47
+ else
48
+ super
49
+ end
50
+ end
51
+
52
+ def update(tuple)
53
+ operand.update(valid_tuple!(tuple))
54
+ end
55
+
56
+ def delete
57
+ operand.delete
58
+ end
59
+
43
60
  def to_ast
44
61
  [ :project, operand.to_ast, attrlist ]
45
62
  end
@@ -56,6 +73,12 @@ module Bmg
56
73
  tuple.delete_if{|k,_| !@attrlist.include?(k) }
57
74
  end
58
75
 
76
+ def valid_tuple!(tuple)
77
+ offending = tuple.keys - attrlist
78
+ raise InvalidUpdateError, "#{offending.inspect} cannot be updated" unless offending.empty?
79
+ tuple
80
+ end
81
+
59
82
  end # class Project
60
83
  end # module Operator
61
84
  end # module Bmg
@@ -31,25 +31,53 @@ module Bmg
31
31
 
32
32
  def each
33
33
  @operand.each do |tuple|
34
- yield rename(tuple)
34
+ yield rename(tuple, renaming)
35
35
  end
36
36
  end
37
37
 
38
+ def insert(arg)
39
+ case arg
40
+ when Hash then operand.insert(rename(arg, reverse_renaming))
41
+ when Relation then operand.insert(arg.rename(reverse_renaming))
42
+ when Enumerable then operand.insert(arg.map{|t| rename(t, reverse_renaming) })
43
+ else
44
+ super
45
+ end
46
+ end
47
+
48
+ def update(arg)
49
+ case arg
50
+ when Hash then operand.update(rename(arg, reverse_renaming))
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ def delete
57
+ operand.delete
58
+ end
59
+
38
60
  def to_ast
39
61
  [ :rename, operand.to_ast, renaming.dup ]
40
62
  end
41
63
 
64
+ protected ### optimization
65
+
66
+ def _restrict(type, predicate)
67
+ operand.restrict(predicate.rename(reverse_renaming)).rename(renaming)
68
+ end
69
+
42
70
  private
43
71
 
44
- def rename(tuple)
72
+ def rename(tuple, renaming)
45
73
  tuple.each_with_object({}){|(k,v),h|
46
- h[rename_key(k)] = v
74
+ h[renaming[k] || k] = v
47
75
  h
48
76
  }
49
77
  end
50
78
 
51
- def rename_key(k)
52
- @renaming[k] || k
79
+ def reverse_renaming
80
+ renaming.each_with_object({}){|(k,v),h| h[v] = k }
53
81
  end
54
82
 
55
83
  end # class Rename
@@ -35,6 +35,23 @@ module Bmg
35
35
  one_or_yield{ nil }
36
36
  end
37
37
 
38
+ def insert(arg)
39
+ raise InvalidUpdateError, "Cannot insert into this Relvar"
40
+ end
41
+
42
+ def update(arg)
43
+ raise InvalidUpdateError, "Cannot update this Relvar"
44
+ end
45
+
46
+ def delete
47
+ raise InvalidUpdateError, "Cannot delete from this Relvar"
48
+ end
49
+
50
+ # Returns a json representation
51
+ def to_json(*args, &bl)
52
+ to_a.to_json(*args, &bl)
53
+ end
54
+
38
55
  # Converts to an sexpr expression.
39
56
  def to_ast
40
57
  raise "Bmg is missing a feature!"
@@ -19,6 +19,18 @@ module Bmg
19
19
  @dataset.each(&bl)
20
20
  end
21
21
 
22
+ def delete
23
+ dataset.delete
24
+ end
25
+
26
+ def insert(arg)
27
+ dataset.insert(arg)
28
+ end
29
+
30
+ def update(arg)
31
+ dataset.update(arg)
32
+ end
33
+
22
34
  def to_ast
23
35
  [:sequel, @dataset.sql]
24
36
  end
@@ -0,0 +1 @@
1
+ require_relative 'support/tuple_algebra'
@@ -0,0 +1,15 @@
1
+ module Bmg
2
+ module TupleAlgebra
3
+
4
+ def allbut(tuple, butlist)
5
+ tuple.reject{|k,v| butlist.include?(k) }
6
+ end
7
+ module_function :allbut
8
+
9
+ def project(tuple, attrlist)
10
+ tuple.reject{|k,v| !attrlist.include?(k) }
11
+ end
12
+ module_function :project
13
+
14
+ end # module TupleAlgebra
15
+ end # module Bmg
@@ -1,8 +1,8 @@
1
1
  module Bmg
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 4
5
- TINY = 1
4
+ MINOR = 5
5
+ TINY = 0
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bmg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.2'
19
+ version: '1.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.2'
26
+ version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -141,6 +141,8 @@ files:
141
141
  - lib/bmg/relation/empty.rb
142
142
  - lib/bmg/sequel.rb
143
143
  - lib/bmg/sequel/relation.rb
144
+ - lib/bmg/support.rb
145
+ - lib/bmg/support/tuple_algebra.rb
144
146
  - lib/bmg/type.rb
145
147
  - lib/bmg/version.rb
146
148
  - tasks/gem.rake