bmg 0.16.4 → 0.16.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec6ef6942310f94d0893f99b34c0d131bed54e0b0d3bee033b10998e09f5b1ef
4
- data.tar.gz: a8fe62d1d072c78c96d9e171f17f8e8f039bd12714c443d7b3921e40d696ef6c
3
+ metadata.gz: 9e4b73e390d1670e392a0e8b69eec34bb0ea7fe837d7da213c2dd58372a56676
4
+ data.tar.gz: 557cc26029356c47b2f93ac960f485faf632b09992f41e53ebe05f7c1a1c735a
5
5
  SHA512:
6
- metadata.gz: 973a0716b0602f10175eec3eff15cd3515b36f58fd2021d65eb1e6a307808534b58f4fc514bac8d742fd82115ba757b99401a6f50314a899331019f2bc3d961f
7
- data.tar.gz: b0f7fb3dba7d8d3810b45b2b0342cacd100ba857969c423f88d28e6c076d1d11879b7a72ced07434ecd88088be93a2dfecb7572cda1a9f396aff4813018c8971
6
+ metadata.gz: 6962061ff3bb5243ea02569621c7b664af1b2659a90d8351c7b39a132abaabf3646bbe2b51dcc44a184bde0ee74b310377d60531670b63d80e70c710961f7493
7
+ data.tar.gz: 275e205ace8d529ffaa72ffbd017292300547899e3d6ca515ac0cfcef1f1fd15b3337dd657c31f5d8a39d12ad929076cc6d7a20b7c174b4f55c5f81a587ceb2a
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # The MIT Licence
2
2
 
3
- Copyright (c) 2017 - Enspirit SPRL (Bernard Lambeau)
3
+ Copyright (c) 2019 - Enspirit SPRL (Bernard Lambeau)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,3 +1,82 @@
1
- ## Bmg, Alf's successor, the relational algebra!
1
+ # Bmg, a relational algebra (Alf's successor)!
2
2
 
3
- Coming soon.
3
+ Bmg is a relational algebra implemented as a ruby library. It implements the
4
+ [Relation as First-Class Citizen](http://www.try-alf.org/blog/2013-10-21-relations-as-first-class-citizen)
5
+ paradigm contributed with Alf a few years ago.
6
+
7
+ Like Alf, Bmg can be used to query relations in memory, from various files,
8
+ SQL databases, and any data sources that can be seen as serving relations.
9
+ Cross data-sources joins are supported, as with Alf.
10
+
11
+ Unlike Alf, Bmg does not make any core ruby extension and exposes the
12
+ object-oriented syntax only (not Alf's functional one). Bmg implementation is
13
+ also much simpler, and make its easier to implement user-defined relations.
14
+
15
+ ## Example
16
+
17
+ ```
18
+ require 'bmg'
19
+ require 'json'
20
+
21
+ suppliers = Bmg::Relation.new([
22
+ { sid: "S1", name: "Smith", status: 20, city: "London" },
23
+ { sid: "S2", name: "Jones", status: 10, city: "Paris" },
24
+ { sid: "S3", name: "Blake", status: 30, city: "Paris" },
25
+ { sid: "S4", name: "Clark", status: 20, city: "London" },
26
+ { sid: "S5", name: "Adams", status: 30, city: "Athens" }
27
+ ])
28
+
29
+ by_city = suppliers
30
+ .restrict(Predicate.neq(status: 30))
31
+ .extend(upname: ->(t){ t[:name].upcase })
32
+ .group([:sid, :name, :status], :suppliers_in)
33
+
34
+ puts JSON.pretty_generate(by_city)
35
+ ```
36
+
37
+ ## Connecting to a SQL database
38
+
39
+ Bmg requires `sequel >= 3.0` to connect to SQL databases.
40
+
41
+ ```
42
+ require 'sqlite3'
43
+ require 'bmg'
44
+ require 'bmg/sequel'
45
+
46
+ DB = Sequel.connect("sqlite://suppliers-and-parts.db")
47
+
48
+ suppliers = Bmg.sequel(:suppliers, DB)
49
+
50
+ puts suppliers
51
+ .restrict(Predicate.neq(status: 30))
52
+ .to_sql
53
+
54
+ # SELECT `t1`.`sid`, `t1`.`name`, `t1`.`status`, `t1`.`city` FROM `suppliers` AS 't1' WHERE (`t1`.`status` != 30)
55
+ ```
56
+
57
+ ## Supported operators
58
+
59
+ ```
60
+ r.allbut([:a, :b, ...]) # remove specified attributes
61
+ r.autowrap(split: '_') # structure a flat relation, split: '_' is the default
62
+ r.autosummarize([:a, :b, ...], x: :sum) # (experimental) usual summarizers supported
63
+ r.constants(x: 12, ...) # add constant attributes (sometimes useful in unions)
64
+ r.extend(x: ->(t){ ... }, ...) # add computed attributes
65
+ r.group([:a, :b, ...], :x) # relation-valued attribute from attributes
66
+ r.image(right, :x, [:a, :b, ...]) # relation-valued attribute from another relation
67
+ r.join(right, [:a, :b, ...]) # natural join on a join key
68
+ r.join(right, :a => :x, :b => :y, ...) # natural join after right reversed renaming
69
+ r.matching(right, [:a, :b, ...]) # semi join, aka where exists
70
+ r.matching(right, :a => :x, :b => :y, ...) # semi join, after right reversed renaming
71
+ r.not_matching(right, [:a, :b, ...]) # inverse semi join, aka where not exists
72
+ r.not_matching(right, :a => :x, ...) # inverse semi join, after right reversed renaming
73
+ r.page([[:a, :asc], ...], 12, page_size: 10) # paging, using an explicit ordering
74
+ r.prefix(:foo_, but: [:a, ...]) # prefix kind of renaming
75
+ r.project([:a, :b, ...]) # keep specified attributes only
76
+ r.rename(a: :x, b: :y, ...) # rename some attributes
77
+ r.restrict(a: "foo", b: "bar", ...) # relational restriction, aka where
78
+ r.rxmatch([:a, :b, ...], /xxx/) # regex match kind of restriction
79
+ r.summarize([:a, :b, ...], x: :sum) # relational summarization
80
+ r.suffix(:_foo, but: [:a, ...]) # suffix kind of renaming
81
+ r.union(right) # relational union
82
+ ```
@@ -152,6 +152,9 @@ module Bmg
152
152
  parts[0...-1].each do |part|
153
153
  sub = (sub[part] ||= {})
154
154
  end
155
+ unless sub.is_a?(Hash)
156
+ raise Bmg::Error, "Autowrap conflict on attribute `#{parts[-2]}`"
157
+ end
155
158
  sub[parts[-1]] = v
156
159
  h
157
160
  }
@@ -75,10 +75,16 @@ module Bmg
75
75
  end
76
76
  protected :_visit
77
77
 
78
+ def y_by_x(y, x, options = {})
79
+ each_with_object({}) do |tuple, h|
80
+ h[tuple[x]] = tuple[y]
81
+ end
82
+ end
83
+
78
84
  def ys_by_x(y, x, options = {})
79
85
  ordering = options[:order]
80
86
  projection = [y, ordering].compact.uniq
81
- by_x = each.each_with_object({}) do |tuple,h|
87
+ by_x = each_with_object({}) do |tuple,h|
82
88
  h[tuple[x]] ||= []
83
89
  h[tuple[x]] << TupleAlgebra.project(tuple, projection)
84
90
  end
@@ -2,7 +2,7 @@ module Bmg
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 16
5
- TINY = 4
5
+ TINY = 5
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  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.16.4
4
+ version: 0.16.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-16 00:00:00.000000000 Z
11
+ date: 2019-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: predicate