Current section

Files

Jump to
qlc lib tutoriald.ex~
Raw

lib/tutoriald.ex~

defmodule TutorialD do
# @spec (list +union+ term) :: maybe_improper_list
##
## row is Dict(columnname, value)
## table is HashSet(row)
def union(left,right) do
Set.union(left, right)
end
def minus(left, right) do
Set.difference(left, right)
end
def intersect(left, right) do
Set.intersection(left, right)
end
def where(left, f) do
Stream.filter(left, f) |> Enum.into(HashSet.new)
end
def project(left, attributes) when is_list(attributes) do
Stream.map(left, fn(x) ->
Dict.take(x, attributes)
end) |> Enum.into(HashSet.new)
end
def fields(left) do
Enum.at(left, 0) |> Map.keys
end
def fnjoin(left, right) do
lkset = fields(left) |> Enum.into(HashSet.new)
rkset = fields(right) |> Enum.into(HashSet.new)
ks = Set.intersection(lkset, rkset)
Enum.reduce(left,
[],
fn(x, acc) ->
z = Enum.filter_map(right,
fn(y) ->
Dict.equal?(Map.take(y, ks),
Map.take(x, ks))
end,
fn(y) ->
Map.merge(x, y)
end)
case z do
[] -> acc
[e] ->
[e|acc]
end
end)
end
defp product(left, right) do
Enum.reduce(left, [],
fn(x, acc) ->
Enum.map(right, &(Dict.merge(x, &1))) |>
Enum.into(acc)
end)
end
def join(left, right) do
if (Enum.count(left) == 0 or Enum.count(right) == 0) do
HashSet.new()
else
fnjoin(left, right) |> Enum.into(HashSet.new)
end
end
def matching(left, right) do
if (Enum.count(left) == 0 or Enum.count(right) == 0) do
HashSet.new()
else
lkset = fields(left)
fnjoin(left, right) |> project(lkset)
end
end
def divideby(left, right) do
fl = fields(left)
fr = fields(right)
fd = fl -- fr
pleft = project(left, fd)
pr = Enum.into(product(pleft, right), HashSet.new)
minus(pleft,
project(minus(pr, left), fd))
end
def rename(left, from, to) do
fl = fields(left)
Enum.reduce(left, HashSet.new,
fn(x, a) ->
v = Dict.get(x, from)
y = Dict.delete(Dict.put(x, to, v), from)
Set.put(a, y)
end)
end
def extend_add(left, fun, x) do
Enum.reduce(left, HashSet.new,
fn(e, a) ->
Set.put(a, Dict.put(e, x, fun.(e)))
end)
end
def update(left, right) do
minus(right, left) |> write!()
end
def write!(left) do
IO.inspect [write: left]
left
end
end