Skip to content

Commit d38b23b

Browse files
authored
Merge pull request #3 from FSou1/feature/introduce-where-statement
Feature/introduce where statement
2 parents 4f2e873 + 48ea34f commit d38b23b

12 files changed

Lines changed: 9725 additions & 217 deletions

File tree

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,25 @@ export interface IDirEntry {
6363
}
6464
```
6565

66-
## Example queries
66+
## Queries
67+
68+
### Supported
6769

6870
`select * from .`
6971

7072
`select * from root`
7173

7274
`select * from root/sub-a`
7375

74-
## TODO
76+
`select * from root where size > 1000000`
77+
78+
`select * from root where size < 1000000`
79+
80+
`select * from root where size = 1000000`
81+
82+
`select * from root where size <> 1000000`
7583

76-
`select * from root where size > 0`
84+
### TODO
7785

7886
`select * from root where isDirectory = true`
7987

deps.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ export {
55
export {
66
assert,
77
assertExists,
8+
assertEquals,
9+
assertThrows
810
} from "https://deno.land/std@0.82.0/testing/asserts.ts";

docs/grammar.peg

Lines changed: 137 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**
2+
* Grammar for validating simple SQL selects.
3+
* @author Marcelo Camargo
4+
* @since 2015/08/26
5+
*
6+
* 2021/04/16: Add '>' and '<' operators (github/FSou1)
7+
*/
8+
19
{
210
var Sql = {
311
listToString: function(x, xs) {
@@ -8,52 +16,153 @@
816

917
Start
1018
= Stmt
11-
19+
1220
Stmt
1321
= SelectStmt
14-
22+
23+
/* Statements */
24+
1525
SelectStmt
16-
= SelectToken
17-
_ x:SelectField xs:SelectFieldRest*
18-
_ FromToken
19-
_ from:Identifier {
20-
return {
21-
type: "select",
22-
fields: [x].concat(xs),
23-
from: from
24-
};
25-
}
26-
27-
SelectToken
28-
= "select"
26+
= _ SelectToken
27+
_ x:SelectField xs:SelectFieldRest*
28+
_ FromToken
29+
_ from:Identifier
30+
_ where:WhereExpr? {
31+
return {
32+
type: "SELECT",
33+
fields: [x].concat(xs),
34+
from: from,
35+
where: where
36+
};
37+
}
2938

30-
SeparatorToken
31-
= ","
32-
33-
FromToken
34-
= "from"
35-
3639
SelectField "select valid field"
37-
= "*"
40+
= Identifier
41+
/ "*"
3842

3943
SelectFieldRest
40-
= SeparatorToken _ s:SelectField {
44+
= _ SeparatorToken _ s:SelectField {
4145
return s;
4246
}
4347

48+
WhereExpr "where expression"
49+
= WhereToken x:LogicExpr xs:LogicExprRest* {
50+
return {
51+
conditions: [x].concat(xs)
52+
};
53+
}
54+
55+
LogicExpr
56+
= _ "(" _ x:LogicExpr xs:LogicExprRest* _ ")" _ {
57+
return [x].concat(xs);
58+
}
59+
/ _ left:Expr _ op:Operator _ right:Expr _ {
60+
return {
61+
left: left,
62+
op: op,
63+
right: right
64+
};
65+
}
66+
67+
LogicExprRest
68+
= _ j:Joiner _ l:LogicExpr {
69+
return {
70+
joiner: j,
71+
expression: l
72+
};
73+
}
74+
75+
Joiner "joiner"
76+
= OrToken { return "Or"; }
77+
/ AndToken { return "And"; }
78+
79+
Operator
80+
= "<>" { return "Different"; }
81+
/ ">" { return "GreaterThan"; }
82+
/ "<" { return "LessThan"; }
83+
/ "=" { return "Equal"; }
84+
/ LikeToken { return "Like"; }
85+
86+
/* Expressions */
87+
88+
Expr
89+
= Float
90+
/ Integer
91+
/ Identifier
92+
/ String
93+
94+
Integer "integer"
95+
= n:[0-9]+ {
96+
return parseInt(n.join(""));
97+
}
98+
99+
Float "float"
100+
= left:Integer "." right:Integer {
101+
return parseFloat([
102+
left.toString(),
103+
right.toString()
104+
].join("."));
105+
}
106+
107+
String "string"
108+
= "'" str:ValidStringChar* "'" {
109+
return str.join("");
110+
}
111+
112+
ValidStringChar
113+
= !"'" c:. {
114+
return c;
115+
}
116+
117+
/* Tokens */
118+
119+
SelectToken
120+
= "SELECT"i !IdentRest
121+
122+
SeparatorToken
123+
= ","
124+
125+
FromToken
126+
= "FROM"i !IdentRest
127+
128+
WhereToken
129+
= "WHERE"i !IdentRest
130+
131+
LikeToken
132+
= "LIKE"i !IdentRest
133+
134+
OrToken
135+
= "OR"i !IdentRest
136+
137+
AndToken
138+
= "AND"i !IdentRest
139+
140+
/* Identifier */
141+
44142
Identifier "identifier"
45143
= x:IdentStart xs:IdentRest* {
46144
return Sql.listToString(x, xs);
47145
}
48-
146+
49147
IdentStart
50148
= [a-z_./]i
51-
149+
52150
IdentRest
53151
= [a-z0-9_/-]i
54152

153+
/* Skip */
55154
_
56-
= ( WhiteSpace )
57-
155+
= ( WhiteSpace / NewLine )*
156+
157+
NewLine "newline"
158+
= "\r\n"
159+
/ "\r"
160+
/ "\n"
161+
/ "\u2028"
162+
/ "\u2029"
163+
58164
WhiteSpace "whitespace"
59-
= " "
165+
= " "
166+
/ "\t"
167+
/ "\v"
168+
/ "\f"

mod_test.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ import { fsselect } from "./mod.ts";
44

55
Deno.test("if 'select * from .' works", async () => {
66
const result = await fsselect("select * from .");
7-
assert(result.length === 16);
7+
assert(result.length === 18);
88
});
99

1010
Deno.test("if 'select * from root' works", async () => {
1111
const result = await fsselect("select * from root");
12-
assert(result.length === 3);
12+
assert(result.length === 4);
1313
});
1414

1515
Deno.test("if 'select * from root/test_folder_with_file' works", async () => {
1616
const result = await fsselect("select * from root/test_folder_with_file");
1717
assert(result.length === 1);
1818
});
19+
20+
Deno.test("if 'select * from root/test_folder_with_files where size > 1000000' works", async () => {
21+
const result = await fsselect("select * from root/test_folder_with_files where size > 1000000");
22+
assert(result.length === 1);
23+
assert(result[0].name === 'b-file-1MB.txt');
24+
});

0 commit comments

Comments
 (0)