-
Notifications
You must be signed in to change notification settings - Fork 0
/
db_lang.js
107 lines (95 loc) · 3.12 KB
/
db_lang.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
const {parse_lang} = require("./dod.js");
const cons_json = (ob) => console.dir(ob, {depth: null, colors: true});
const {join, relvar, minus, union, rename, selection, inv_selection} = require("./main.js");
/**
*
* @param {import("./dod_dts").Branch} branch
*/
function resolve_primitive(branch) {
switch(branch.type) {
case "NUMBER": return branch.value;
case "VAR": return branch.value;
}
console.error("Not a primitive: ");
cons_json(ob);
throw `Not a primitive.`;
}
/**
*
* @param {import("./dod_dts").Branch} branch
*/
function is_primitive(branch){
return ["VAR", "NUMBER"].includes(branch.type);
}
/**
*
* @param {import("./dod_dts").Branch} branch
*/
function is_relvar(branch, relvars){
return branch.type == "VAR" && relvars[branch.value] != undefined;
}
/**
*
* @param {import("./dod_dts").Branch} branch
* @param {import("./rv_types").DB['data']['relvars']} relvars
*/
function resolve_relvar(branch, relvars) {
const rv = relvars[branch.value];
if(rv == undefined) throw `Cannot find relvar: ${branch.value}`;
return rv;
}
/**
*
* @param {import("./dod_dts").Branch} branch
* @param {import("./rv_types").DB['data']['relvars']} relvars
*/
function parse_branch(branch, relvars){
const resolve_or_relvar = (br) => is_relvar(br, relvars) ? resolve_relvar(br, relvars) : parse_branch(br, relvars);
switch(branch.type) {
case "assign": {return;}
case "binary": {
switch(branch.operator) {
case "JOIN": {
return join(resolve_or_relvar(branch.left), resolve_or_relvar(branch.right));
}
case "MINUS": {
return minus(resolve_or_relvar(branch.left), resolve_or_relvar(branch.right));
}
case "UNION": {
return union(resolve_or_relvar(branch.left), resolve_or_relvar(branch.right));
}
case "RENAME": {
return rename(resolve_or_relvar(branch.left), ...branch.right.map( (b) => [b.left.value, b.right.value]))
}
}
}
case "select": {
if(branch.right.type == "tree") {
return selection(resolve_or_relvar(branch.left), ...branch.right.branches.map(v=>v.value));
}else if(branch.right.type == "VAR"){
return selection(resolve_or_relvar(branch.left), branch.right.value);
}else if(branch.right.type == "all_but") {
const rv = resolve_or_relvar(branch.left);
const butt = branch.right.attrs.map(v=>v.value);
return inv_selection(rv, ...butt)
}
}
}
}
/**
* @param {ReturnType<parse_lang>} tree
* @param {import("./rv_types").DB['data']['relvars']} relvars
*/
function parse_tree(tree, relvars){
return parse_branch(tree[0], relvars);
}
/**
* Runs a command on a given DB.
* @param {import("./rv_types").DB} DB
* @param {string} CMD
*/
function db_run_cmd(DB, CMD) {
const tree = parse_lang(CMD);
return parse_tree(tree, DB.data.relvars)
}
module.exports = {run: db_run_cmd}