bmg 0.16.4 → 0.16.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.md +1 -1
- data/README.md +81 -2
- data/lib/bmg/operator/autowrap.rb +3 -0
- data/lib/bmg/relation.rb +7 -1
- data/lib/bmg/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e4b73e390d1670e392a0e8b69eec34bb0ea7fe837d7da213c2dd58372a56676
|
4
|
+
data.tar.gz: 557cc26029356c47b2f93ac960f485faf632b09992f41e53ebe05f7c1a1c735a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
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
|
-
|
1
|
+
# Bmg, a relational algebra (Alf's successor)!
|
2
2
|
|
3
|
-
|
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
|
+
```
|
data/lib/bmg/relation.rb
CHANGED
@@ -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 =
|
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
|
data/lib/bmg/version.rb
CHANGED
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
|
+
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-
|
11
|
+
date: 2019-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: predicate
|