bmg 0.19.3 → 0.20.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
  SHA256:
3
- metadata.gz: 773942a08ee8480d73b6d455ef2560c1136002223c86b38ff549beaf280e2760
4
- data.tar.gz: 22043853a3d11acde72865db0ad870f2fe033a71e9474ffb1451cc4d69a58d30
3
+ metadata.gz: 527bf7476d384f3f1be70ff1f77d1886ac75e4c9bbd8fe8e868fefa9971ff34e
4
+ data.tar.gz: 628ce8e51b75d3244d937f71b1283556ac16a72835aa9cb415f23c8fbb77fc39
5
5
  SHA512:
6
- metadata.gz: 96dc776f81d2b15093372b843e4bb20c4207e0e59a44842130cb79035fd06ab32fb633f34479c2022b7ad5c958ade798fdc10f07cdcf8db60848d382554067eb
7
- data.tar.gz: fa08f7f03dc62e03302e82e68ba0b32505c1fce2f8a78c498c40894de37e1e486e60104e18a7e84761ea56b947bf6c585825ce2462a702b0e85d30601a138ac5
6
+ metadata.gz: 8948e29965019a1e5fc1204d71a3a423602ea35d4a72ef5e61a7baf12a89f2e653e1428bb4969e731b8ae684e78171c2be0c7c330494c55821d4914b89c46635
7
+ data.tar.gz: 26e67c96891ed6009c8e8ba1f601053acf71c38951fe0a905c289db83bab40be9809ffabd7c2b5b6287fc9cae1aa6cd1b51dea71cd42f85a9aa77dbfdb70b2bd
data/README.md CHANGED
@@ -16,6 +16,7 @@ further down this README.
16
16
  * [Memory relations](#memory-relations)
17
17
  * [Connecting to SQL databases](#connecting-to-sql-databases)
18
18
  * [Reading files (csv, excel, text)](#reading-files-csv-excel-text)
19
+ * [Connecting to Redis databases](#connecting-to-redis-databases)
19
20
  * [Your own relations](#your-own-relations)
20
21
  * [List of supported operators](#supported-operators)
21
22
  * [How is this different?](#how-is-this-different)
@@ -172,6 +173,43 @@ r.type.attrlist
172
173
  In this scenario, non matching lines are skipped. The `:line` attribute keeps
173
174
  being used to have at least one candidate key (so to speak).
174
175
 
176
+ ### Connecting to Redis databases
177
+
178
+ Bmg currently requires `bmg-redis` and `redis >= 4.6` to connect
179
+ to Redis databases. You also need to require `bmg/redis`.
180
+
181
+ ```Gemfile
182
+ gem 'bmg'
183
+ gem 'bmg-redis'
184
+ ```
185
+
186
+ ```ruby
187
+ require 'redis' # also done by 'bmg/redis' below
188
+ require 'bmg'
189
+ require 'bmg/redis'
190
+ ```
191
+
192
+ Then, you can create Redis relation variables (aka relvars) like
193
+ this:
194
+
195
+ ```ruby
196
+ type = Bmg::Type::ANY.with_keys([[:id]])
197
+ r = Bmg.redis(type, {
198
+ key_prefix: "suppliers",
199
+ redis: Redis.new,
200
+ serializer: :marshal
201
+ })
202
+ ```
203
+
204
+ The key prefix will be used to distinguish the tuples from other
205
+ elements in the same database (e.g. tuples from other relvars).
206
+ The serializer is either `:marshal` or `:json`. Please note that
207
+ types are not preserved when using the second one (all attribute
208
+ values will come back as strings, but keys will be symbolized).
209
+
210
+ The redis relvars support basic algorithms for insert/update/delete.
211
+ No optimization is currently supported.
212
+
175
213
  ### Your own relations
176
214
 
177
215
  As noted earlier, Bmg has a simple relation interface where you only have to
@@ -50,12 +50,12 @@ module Bmg
50
50
  end
51
51
  end
52
52
 
53
- def update(tuple)
54
- operand.update(valid_tuple!(tuple))
53
+ def update(tuple, predicate = Predicate.tautology)
54
+ operand.update(valid_tuple!(tuple), predicate)
55
55
  end
56
56
 
57
- def delete
58
- operand.delete
57
+ def delete(predicate = Predicate.tautology)
58
+ operand.delete(predicate)
59
59
  end
60
60
 
61
61
  def to_ast
@@ -10,15 +10,15 @@ module Bmg
10
10
  class Constants
11
11
  include Operator::Unary
12
12
 
13
- def initialize(type, operand, constants)
13
+ def initialize(type, operand, the_constants)
14
14
  @type = type
15
15
  @operand = operand
16
- @constants = constants
16
+ @the_constants = the_constants
17
17
  end
18
18
 
19
19
  protected
20
20
 
21
- attr_reader :constants
21
+ attr_reader :the_constants
22
22
 
23
23
  public
24
24
 
@@ -32,27 +32,27 @@ module Bmg
32
32
  def insert(arg)
33
33
  case arg
34
34
  when Hash then operand.insert(allbut_constants(arg))
35
- when Relation then operand.insert(arg.allbut(constants.keys))
35
+ when Relation then operand.insert(arg.allbut(the_constants.keys))
36
36
  when Enumerable then operand.insert(arg.map{|t| allbut_constants(t) })
37
37
  else
38
38
  super
39
39
  end
40
40
  end
41
41
 
42
- def update(tuple)
43
- shared = tuple.keys & constants.keys
42
+ def update(tuple, predicate = Predicate.tautology)
43
+ shared = tuple.keys & the_constants.keys
44
44
  on_tuple = TupleAlgebra.project(tuple, shared)
45
- on_const = TupleAlgebra.project(constants, shared)
45
+ on_const = TupleAlgebra.project(the_constants, shared)
46
46
  raise InvalidUpdateError, "Cannot violate relvar predicate" unless on_tuple == on_const
47
- operand.update(allbut_constants(tuple))
47
+ operand.update(allbut_constants(tuple), predicate)
48
48
  end
49
49
 
50
- def delete
51
- operand.delete
50
+ def delete(predicate = Predicate.tautology)
51
+ operand.delete(predicate)
52
52
  end
53
53
 
54
54
  def to_ast
55
- [ :constants, operand.to_ast, constants.dup ]
55
+ [ :constants, operand.to_ast, the_constants.dup ]
56
56
  end
57
57
 
58
58
  public ### for internal reasons
@@ -65,32 +65,32 @@ module Bmg
65
65
 
66
66
  def _page(type, ordering, page_index, options)
67
67
  attrs = ordering.map{|(k,v)| k}
68
- cs_attrs = constants.keys
68
+ cs_attrs = the_constants.keys
69
69
  if (attrs & cs_attrs).empty?
70
70
  operand
71
71
  .page(ordering, page_index, options)
72
- .constants(constants)
72
+ .constants(the_constants)
73
73
  else
74
74
  super
75
75
  end
76
76
  end
77
77
 
78
78
  def _restrict(type, predicate)
79
- # bottom_p makes no reference to constants, top_p possibly
79
+ # bottom_p makes no reference to the_constants, top_p possibly
80
80
  # does...
81
- top_p, bottom_p = predicate.and_split(constants.keys)
81
+ top_p, bottom_p = predicate.and_split(the_constants.keys)
82
82
  if top_p.tautology?
83
- # push all situation: predicate made no reference to constants
83
+ # push all situation: predicate made no reference to the_constants
84
84
  result = operand
85
85
  result = result.restrict(bottom_p)
86
- result = result.constants(constants)
86
+ result = result.constants(the_constants)
87
87
  result
88
- elsif (top_p.free_variables - constants.keys).empty?
89
- # top_p applies to constants only
90
- if eval = top_p.evaluate(constants)
88
+ elsif (top_p.free_variables - the_constants.keys).empty?
89
+ # top_p applies to the_constants only
90
+ if eval = top_p.evaluate(the_constants)
91
91
  result = operand
92
92
  result = result.restrict(bottom_p)
93
- result = result.constants(constants)
93
+ result = result.constants(the_constants)
94
94
  result
95
95
  else
96
96
  Relation.empty(type)
@@ -104,7 +104,7 @@ module Bmg
104
104
  # of them
105
105
  result = operand
106
106
  result = result.restrict(bottom_p)
107
- result = result.constants(constants)
107
+ result = result.constants(the_constants)
108
108
  result = result.restrict(top_p)
109
109
  result
110
110
  end
@@ -115,17 +115,17 @@ module Bmg
115
115
  protected ### inspect
116
116
 
117
117
  def args
118
- [ constants ]
118
+ [ the_constants ]
119
119
  end
120
120
 
121
121
  private
122
122
 
123
123
  def extend_it(tuple)
124
- tuple.merge(@constants)
124
+ tuple.merge(@the_constants)
125
125
  end
126
126
 
127
127
  def allbut_constants(tuple)
128
- TupleAlgebra.allbut(tuple, constants.keys)
128
+ TupleAlgebra.allbut(tuple, the_constants.keys)
129
129
  end
130
130
 
131
131
  end # class Constants
@@ -42,12 +42,12 @@ module Bmg
42
42
  end
43
43
  end
44
44
 
45
- def update(tuple)
46
- operand.update(allbut_extkeys(tuple))
45
+ def update(tuple, predicate = Predicate.tautology)
46
+ operand.update(allbut_extkeys(tuple), predicate)
47
47
  end
48
48
 
49
- def delete
50
- operand.delete
49
+ def delete(predicate = Predicate.tautology)
50
+ operand.delete(predicate)
51
51
  end
52
52
 
53
53
  def to_ast
@@ -49,12 +49,12 @@ module Bmg
49
49
  end
50
50
  end
51
51
 
52
- def update(tuple)
53
- operand.update(valid_tuple!(tuple))
52
+ def update(tuple, predicate = Predicate.tautology)
53
+ operand.update(valid_tuple!(tuple), predicate)
54
54
  end
55
55
 
56
- def delete
57
- operand.delete
56
+ def delete(predicate = Predicate.tautology)
57
+ operand.delete(predicate)
58
58
  end
59
59
 
60
60
  def to_ast
@@ -45,16 +45,17 @@ module Bmg
45
45
  end
46
46
  end
47
47
 
48
- def update(arg)
48
+ def update(arg, predicate = Predicate.tautology)
49
49
  case arg
50
- when Hash then operand.update(rename_tuple(arg, reverse_renaming))
50
+ when Hash
51
+ operand.update(rename_tuple(arg, reverse_renaming), predicate)
51
52
  else
52
53
  super
53
54
  end
54
55
  end
55
56
 
56
- def delete
57
- operand.delete
57
+ def delete(predicate = Predicate.tautology)
58
+ operand.delete(predicate)
58
59
  end
59
60
 
60
61
  def to_ast
@@ -32,6 +32,18 @@ module Bmg
32
32
  end
33
33
  end
34
34
 
35
+ def insert(tuple)
36
+ operand.insert(tuple)
37
+ end
38
+
39
+ def update(updating, predicate = Predicate.tautology)
40
+ operand.update(updating, predicate & self.predicate)
41
+ end
42
+
43
+ def delete(predicate = Predicate.tautology)
44
+ operand.delete(predicate & self.predicate)
45
+ end
46
+
35
47
  def to_ast
36
48
  [ :restrict, operand.to_ast, predicate.sexpr ]
37
49
  end
@@ -39,9 +39,7 @@ module Bmg
39
39
  private
40
40
 
41
41
  def tuple(row)
42
- row.to_hash.each_with_object({}){|(k,v),h|
43
- h[k.to_sym] = v
44
- }
42
+ row.to_hash.each_with_object({}){|(k,v),h| h[k.to_sym] = v }
45
43
  end
46
44
 
47
45
  def handle_type(type)
@@ -0,0 +1,23 @@
1
+ module Bmg
2
+ module Relation
3
+ class InMemory
4
+ class Mutable < InMemory
5
+ def insert(arg)
6
+ raise ArgumentError unless arg.is_a?(Hash)
7
+
8
+ @operand << arg.dup
9
+ end
10
+
11
+ def update(updating, predicate = Predicate.tautology)
12
+ @operand = @operand.map{|t|
13
+ predicate.call(t) ? t.merge(updating) : t
14
+ }
15
+ end
16
+
17
+ def delete(predicate = Predicate.tautology)
18
+ @operand = @operand.select{|t| predicate.call(t) }
19
+ end
20
+ end # class Mutable
21
+ end # class InMemory
22
+ end # module Relation
23
+ end # module Bmg
@@ -41,3 +41,4 @@ module Bmg
41
41
  end # class InMemory
42
42
  end # module Relation
43
43
  end # module Bmg
44
+ require_relative 'in_memory/mutable'
data/lib/bmg/relation.rb CHANGED
@@ -74,16 +74,16 @@ module Bmg
74
74
  one_or_yield{ nil }
75
75
  end
76
76
 
77
- def insert(arg)
78
- raise InvalidUpdateError, "Cannot insert into this Relvar"
77
+ def insert(*args, &bl)
78
+ raise InvalidUpdateError, "Cannot insert into #{self.class.name}"
79
79
  end
80
80
 
81
- def update(arg)
82
- raise InvalidUpdateError, "Cannot update this Relvar"
81
+ def update(*args, &bl)
82
+ raise InvalidUpdateError, "Cannot update #{self.class.name}"
83
83
  end
84
84
 
85
- def delete
86
- raise InvalidUpdateError, "Cannot delete from this Relvar"
85
+ def delete(*args, &bl)
86
+ raise InvalidUpdateError, "Cannot delete from #{self.class.name}"
87
87
  end
88
88
 
89
89
  def visit(&visitor)
@@ -0,0 +1,22 @@
1
+ module Bmg
2
+ module Sequel
3
+ class PredicateTranslator < Sexpr::Processor
4
+ include ::Predicate::ToSequel::Methods
5
+
6
+ def initialize(parent)
7
+ @parent = parent
8
+ end
9
+
10
+ public ### Predicate hack
11
+
12
+ def on_opaque(sexpr)
13
+ @parent.apply(sexpr.last)
14
+ end
15
+
16
+ def on_exists(sexpr)
17
+ @parent.apply(sexpr.last).exists
18
+ end
19
+
20
+ end # class PredicateTranslator
21
+ end # module Sequel
22
+ end # module Bmg
@@ -13,8 +13,13 @@ module Bmg
13
13
  dataset.each(&bl)
14
14
  end
15
15
 
16
- def delete
17
- base_table.delete
16
+ def delete(predicate = Predicate.tautology)
17
+ target = base_table
18
+ unless predicate.tautology?
19
+ compiled = compile_predicate(predicate)
20
+ target = base_table.where(compiled)
21
+ end
22
+ target.delete
18
23
  end
19
24
 
20
25
  def insert(arg)
@@ -30,8 +35,13 @@ module Bmg
30
35
  end
31
36
  end
32
37
 
33
- def update(arg)
34
- base_table.update(arg)
38
+ def update(arg, predicate = Predicate.tautology)
39
+ target = base_table
40
+ unless predicate.tautology?
41
+ compiled = compile_predicate(predicate)
42
+ target = base_table.where(compiled)
43
+ end
44
+ target.update(arg)
35
45
  end
36
46
 
37
47
  def _count
@@ -73,6 +83,10 @@ module Bmg
73
83
  operand.expr
74
84
  end
75
85
 
86
+ def compile_predicate(predicate)
87
+ Translator.new(sequel_db).compile_predicate(predicate)
88
+ end
89
+
76
90
  end # class Relation
77
91
  end # module Sequel
78
92
  end # module Bmg
@@ -179,36 +179,19 @@ module Bmg
179
179
  sexpr.last
180
180
  end
181
181
 
182
- private
183
-
184
- def dataset(expr)
185
- return expr if ::Sequel::Dataset===expr
186
- sequel_db[expr]
187
- end
182
+ public
188
183
 
189
184
  def compile_predicate(predicate)
190
185
  PredicateTranslator.new(self).call(predicate)
191
186
  end
192
187
 
193
- class PredicateTranslator < Sexpr::Processor
194
- include ::Predicate::ToSequel::Methods
195
-
196
- def initialize(parent)
197
- @parent = parent
198
- end
199
-
200
- public ### Predicate hack
201
-
202
- def on_opaque(sexpr)
203
- @parent.apply(sexpr.last)
204
- end
188
+ private
205
189
 
206
- def on_exists(sexpr)
207
- @parent.apply(sexpr.last).exists
190
+ def dataset(expr)
191
+ return expr if ::Sequel::Dataset===expr
192
+ sequel_db[expr]
208
193
  end
209
194
 
210
- end
211
-
212
195
  end # class Translator
213
196
  end # module Sequel
214
197
  end # module Bmg
data/lib/bmg/sequel.rb CHANGED
@@ -62,5 +62,6 @@ module Bmg
62
62
  end
63
63
  require_relative 'sequel/ext'
64
64
  require_relative 'sequel/translator'
65
+ require_relative 'sequel/predicate_translator'
65
66
  require_relative 'sequel/type_inference'
66
67
  require_relative 'sequel/relation'
@@ -27,15 +27,15 @@ module Bmg
27
27
  raise NotImplementedError
28
28
  end
29
29
 
30
- def delete
30
+ def delete(*args, &bl)
31
31
  raise NotImplementedError
32
32
  end
33
33
 
34
- def insert(arg)
34
+ def insert(*args, &bl)
35
35
  raise NotImplementedError
36
36
  end
37
37
 
38
- def update(arg)
38
+ def update(*args, &bl)
39
39
  raise NotImplementedError
40
40
  end
41
41
 
@@ -2,13 +2,7 @@ module Bmg
2
2
  class Ordering
3
3
 
4
4
  def initialize(attrs)
5
- @attrs = if attrs.empty?
6
- []
7
- elsif attrs.first.is_a?(Symbol)
8
- attrs.map{|a| [a, :asc] }
9
- else
10
- attrs
11
- end
5
+ @attrs = attrs
12
6
  end
13
7
  attr_reader :attrs
14
8
 
@@ -39,9 +33,5 @@ module Bmg
39
33
  0
40
34
  end
41
35
 
42
- def to_a
43
- attrs.to_a
44
- end
45
-
46
36
  end # class Ordering
47
37
  end # module Bmg
@@ -3,7 +3,6 @@ module Bmg
3
3
 
4
4
  DEFAULT_PREFS = {
5
5
  attributes_ordering: nil,
6
- tuple_ordering: nil,
7
6
  extra_attributes: :after
8
7
  }
9
8
 
@@ -18,12 +17,6 @@ module Bmg
18
17
  new(arg)
19
18
  end
20
19
 
21
- def tuple_ordering
22
- return nil unless to = options[:tuple_ordering]
23
-
24
- @tuple_ordering = Ordering.new(to)
25
- end
26
-
27
20
  def attributes_ordering
28
21
  options[:attributes_ordering]
29
22
  end
@@ -32,29 +25,10 @@ module Bmg
32
25
  options[:extra_attributes]
33
26
  end
34
27
 
35
- def grouping_attributes
36
- options[:grouping_attributes]
37
- end
38
-
39
- def erase_redundance_in_group(before, current)
40
- return [nil, current] unless ga = grouping_attributes
41
- return [current, current] unless before
42
-
43
- new_before, new_current = current.dup, current.dup
44
- ga.each do |attr|
45
- return [new_before, new_current] unless before[attr] == current[attr]
46
- new_current[attr] = nil
47
- end
48
- [new_before, new_current]
49
- end
50
-
51
28
  def order_attrlist(attrlist)
52
29
  return attrlist if attributes_ordering.nil?
53
-
54
30
  index = Hash[attributes_ordering.each_with_index.to_a]
55
- base = attrlist
56
- base = attrlist & attributes_ordering if extra_attributes == :ignored
57
- base.sort{|a,b|
31
+ attrlist.sort{|a,b|
58
32
  ai, bi = index[a], index[b]
59
33
  if ai && bi
60
34
  ai <=> bi
data/lib/bmg/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Bmg
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 19
5
- TINY = 3
4
+ MINOR = 20
5
+ TINY = 0
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
@@ -16,14 +16,12 @@ module Bmg
16
16
  require 'csv'
17
17
  string_or_io, to_s = string_or_io.nil? ? [StringIO.new, true] : [string_or_io, false]
18
18
  headers, csv = infer_headers(relation.type), nil
19
- previous = nil
20
- each_tuple(relation) do |tuple,i|
19
+ relation.each do |tuple|
21
20
  if csv.nil?
22
21
  headers = infer_headers(tuple) if headers.nil?
23
22
  csv_opts = csv_options.merge(headers: headers)
24
23
  csv = CSV.new(string_or_io, **csv_opts)
25
24
  end
26
- previous, tuple = output_preferences.erase_redundance_in_group(previous, tuple)
27
25
  csv << headers.map{|h| tuple[h] }
28
26
  end
29
27
  to_s ? string_or_io.string : string_or_io
@@ -6,11 +6,11 @@ module Bmg
6
6
  DEFAULT_OPTIONS = {
7
7
  }
8
8
 
9
- def initialize(xlsx_options, output_preferences = nil)
10
- @xlsx_options = DEFAULT_OPTIONS.merge(xlsx_options)
9
+ def initialize(csv_options, output_preferences = nil)
10
+ @csv_options = DEFAULT_OPTIONS.merge(csv_options)
11
11
  @output_preferences = OutputPreferences.dress(output_preferences)
12
12
  end
13
- attr_reader :xlsx_options, :output_preferences
13
+ attr_reader :csv_options, :output_preferences
14
14
 
15
15
  def call(relation, path)
16
16
  require 'write_xlsx'
@@ -21,24 +21,22 @@ module Bmg
21
21
  attr_reader :workbook, :worksheet
22
22
 
23
23
  def _call(relation, path)
24
- @workbook = xlsx_options[:workbook] || WriteXLSX.new(path)
25
- @worksheet = xlsx_options[:worksheet] || workbook.add_worksheet
24
+ @workbook = WriteXLSX.new(path)
25
+ @worksheet = workbook.add_worksheet
26
26
 
27
27
  headers = infer_headers(relation.type)
28
- before = nil
29
- each_tuple(relation) do |tuple,i|
28
+ relation.each_with_index do |tuple,i|
30
29
  headers = infer_headers(tuple) if headers.nil?
31
30
  headers.each_with_index do |h,i|
32
31
  worksheet.write_string(0, i, h)
33
32
  end if i == 0
34
- before, tuple = output_preferences.erase_redundance_in_group(before, tuple)
35
33
  headers.each_with_index do |h,j|
36
34
  meth, *args = write_pair(tuple[h])
37
35
  worksheet.send(meth, 1+i, j, *args)
38
36
  end
39
37
  end
40
38
 
41
- workbook.close unless xlsx_options[:workbook]
39
+ workbook.close
42
40
  path
43
41
  end
44
42
 
data/lib/bmg/writer.rb CHANGED
@@ -12,17 +12,6 @@ module Bmg
12
12
  attrlist ? output_preferences.order_attrlist(attrlist) : nil
13
13
  end
14
14
 
15
- def each_tuple(relation, &bl)
16
- if ordering = output_preferences.tuple_ordering
17
- relation
18
- .to_a
19
- .sort{|t1,t2| ordering.compare_attrs(t1, t2) }
20
- .each_with_index(&bl)
21
- else
22
- relation.each_with_index(&bl)
23
- end
24
- end
25
-
26
15
  end # module Writer
27
16
  end # module Bmg
28
17
  require_relative 'writer/csv'
data/lib/bmg.rb CHANGED
@@ -4,6 +4,11 @@ require 'forwardable'
4
4
  require 'set'
5
5
  module Bmg
6
6
 
7
+ def mutable(enumerable, type = Type::ANY)
8
+ Relation::InMemory::Mutable.new(type, enumerable).spied(main_spy)
9
+ end
10
+ module_function :mutable
11
+
7
12
  def in_memory(enumerable, type = Type::ANY)
8
13
  Relation::InMemory.new(type, enumerable).spied(main_spy)
9
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bmg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.3
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-18 00:00:00.000000000 Z
11
+ date: 2022-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: predicate
@@ -174,11 +174,13 @@ files:
174
174
  - lib/bmg/relation.rb
175
175
  - lib/bmg/relation/empty.rb
176
176
  - lib/bmg/relation/in_memory.rb
177
+ - lib/bmg/relation/in_memory/mutable.rb
177
178
  - lib/bmg/relation/materialized.rb
178
179
  - lib/bmg/relation/proxy.rb
179
180
  - lib/bmg/relation/spied.rb
180
181
  - lib/bmg/sequel.rb
181
182
  - lib/bmg/sequel/ext.rb
183
+ - lib/bmg/sequel/predicate_translator.rb
182
184
  - lib/bmg/sequel/relation.rb
183
185
  - lib/bmg/sequel/translator.rb
184
186
  - lib/bmg/sequel/type_inference.rb
@@ -318,7 +320,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
318
320
  - !ruby/object:Gem::Version
319
321
  version: '0'
320
322
  requirements: []
321
- rubygems_version: 3.1.6
323
+ rubygems_version: 3.1.4
322
324
  signing_key:
323
325
  specification_version: 4
324
326
  summary: Bmg is Alf's successor.