Skip to content

Commit 245a154

Browse files
authored
Merge pull request #15 from FSou1/feature/9-sql-like
Feature/9 sql like
2 parents 21116ab + 941f230 commit 245a154

5 files changed

Lines changed: 179 additions & 10 deletions

File tree

README.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export interface IDirEntry {
6767

6868
### Operators
6969

70-
The list of supported operators: `>`, `<`, `=`, `<>`.
70+
The list of supported operators: `>`, `<`, `=`, `<>`, `like`.
7171

7272
### Supported
7373

@@ -85,10 +85,4 @@ The list of supported operators: `>`, `<`, `=`, `<>`.
8585

8686
`select * from root where name = 'root.txt'`
8787

88-
### TODO
89-
90-
`select * from root where name like '%txt'`
91-
92-
`select * from root where name like '%txt%'`
93-
94-
`select * from root where name like 'txt%'`
88+
`select * from root where name like '%.txt'`

like.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function getLikeRegExp(input: string): RegExp {
2+
const pattern = input
3+
.replaceAll(".", "\\.")
4+
.replaceAll("%", ".*?");
5+
6+
return new RegExp("^" + pattern + "$");
7+
}

like_test.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { assert, assertEquals } from "./deps.ts";
2+
import { getLikeRegExp } from "./like.ts";
3+
4+
Deno.test("where name like 'abc.txt'", () => {
5+
const regexp = getLikeRegExp("abc.txt");
6+
7+
/* Match */
8+
assert("abc.txt".match(regexp));
9+
10+
/* Does not match */
11+
assertEquals("a.txt".match(regexp), null);
12+
assertEquals("abc_d.txt".match(regexp), null);
13+
assertEquals("abc.tx".match(regexp), null);
14+
});
15+
16+
Deno.test("where name like '%.txt'", () => {
17+
const regexp = getLikeRegExp("%.txt");
18+
19+
/* Match */
20+
assert("abc.txt".match(regexp));
21+
assert("c.txt".match(regexp));
22+
assert("ab_c.txt".match(regexp));
23+
assert("ab_-\/*+ddc.txt".match(regexp));
24+
25+
/* Does not match */
26+
assertEquals("abc.bin".match(regexp), null);
27+
assertEquals(".txn".match(regexp), null);
28+
assertEquals("abc_txt".match(regexp), null);
29+
assertEquals("abc.!txt".match(regexp), null);
30+
assertEquals("abc.txt_bin".match(regexp), null);
31+
});
32+
33+
Deno.test("where name like '%.txt%'", () => {
34+
const regexp = getLikeRegExp("%.txt%");
35+
36+
/* Match */
37+
assert("abc.txt".match(regexp));
38+
assert("c.txt".match(regexp));
39+
assert("ab_c.txt".match(regexp));
40+
assert("ab_-\/*+ddc.txt".match(regexp));
41+
42+
/* Does not match */
43+
assertEquals("abc.bin".match(regexp), null);
44+
assertEquals(".txn".match(regexp), null);
45+
assertEquals("abc_txt".match(regexp), null);
46+
});
47+
48+
Deno.test("where name like 'ab%txt'", () => {
49+
const regexp = getLikeRegExp("ab%txt");
50+
51+
/* Match */
52+
assert("abc.txt".match(regexp));
53+
assert("abdef_.txt".match(regexp));
54+
assert("ab_c.txt".match(regexp));
55+
assert("ab_-\/*+ddc.txt".match(regexp));
56+
57+
/* Does not match */
58+
assertEquals("abc.bin".match(regexp), null);
59+
assertEquals("abc".match(regexp), null);
60+
assertEquals("d_abc.txt".match(regexp), null);
61+
assertEquals("abc.txt.".match(regexp), null);
62+
assertEquals("abc.txt!".match(regexp), null);
63+
});
64+
65+
Deno.test("where name like 'abc.%'", () => {
66+
const regexp = getLikeRegExp("abc.%");
67+
68+
/* Match */
69+
assert("abc.txt".match(regexp));
70+
assert("abc.bin".match(regexp));
71+
assert("abc.".match(regexp));
72+
73+
/* Does not match */
74+
assertEquals("abc".match(regexp), null);
75+
assertEquals("d".match(regexp), null);
76+
assertEquals("abc?.".match(regexp), null);
77+
});
78+
79+
Deno.test("where name like '%.%'", () => {
80+
const regexp = getLikeRegExp("%.%");
81+
82+
/* Match */
83+
assert("abc.txt".match(regexp));
84+
assert("abc.bin".match(regexp));
85+
assert("abc.".match(regexp));
86+
assert(".".match(regexp));
87+
assert(".txt".match(regexp));
88+
89+
/* Does not match */
90+
assertEquals("abc".match(regexp), null);
91+
});

mod_test.ts

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ 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 === 18);
7+
assert(result.length === 20);
88
});
99

1010
Deno.test("if 'select * from root' works", async () => {
@@ -147,4 +147,76 @@ Deno.test("if select * from root where name <> 'root.txt' works", async () => {
147147
"test_folder_with_folder",
148148
];
149149
assertArrayIncludes<string>(names, expectedNames);
150+
});
151+
152+
Deno.test("if select * from root where name like 'test_%' works", async () => {
153+
const result = await fsselect("select * from root where name like 'test_%'");
154+
assert(result.length === 3);
155+
156+
const names = result.map((i) => i.name as string);
157+
const expectedNames = [
158+
"test_folder_with_file",
159+
"test_folder_with_files",
160+
"test_folder_with_folder",
161+
];
162+
assertArrayIncludes<string>(names, expectedNames);
163+
});
164+
165+
Deno.test("if select * from root where name like '%folder%' works", async () => {
166+
const result = await fsselect("select * from root where name like '%folder%'");
167+
assert(result.length === 3);
168+
169+
const names = result.map((i) => i.name as string);
170+
const expectedNames = [
171+
"test_folder_with_file",
172+
"test_folder_with_files",
173+
"test_folder_with_folder",
174+
];
175+
assertArrayIncludes<string>(names, expectedNames);
176+
});
177+
178+
Deno.test("if select * from root where name like '%.txt' works", async () => {
179+
const result = await fsselect("select * from root where name like '%.txt'");
180+
assert(result.length === 1);
181+
182+
const names = result.map((i) => i.name as string);
183+
const expectedNames = [
184+
"root.txt"
185+
];
186+
assertArrayIncludes<string>(names, expectedNames);
187+
});
188+
189+
Deno.test("if select * from root where name like '%with_file%' works", async () => {
190+
const result = await fsselect("select * from root where name like '%with_file%'");
191+
assert(result.length === 2);
192+
193+
const names = result.map((i) => i.name as string);
194+
const expectedNames = [
195+
"test_folder_with_file",
196+
"test_folder_with_files",
197+
];
198+
assertArrayIncludes<string>(names, expectedNames);
199+
});
200+
201+
Deno.test("if select * from root where name like 'some' does not return entries", async () => {
202+
const result = await fsselect("select * from root where name like 'some'");
203+
assert(result.length === 0);
204+
205+
const names = result.map((i) => i.name as string);
206+
const expectedNames: string[] = [];
207+
assertArrayIncludes<string>(names, expectedNames);
208+
});
209+
210+
Deno.test("if select * from root where name like '%%' works", async () => {
211+
const result = await fsselect("select * from root where name like '%%'");
212+
assert(result.length === 4);
213+
214+
const names = result.map((i) => i.name as string);
215+
const expectedNames = [
216+
"test_folder_with_file",
217+
"test_folder_with_files",
218+
"test_folder_with_folder",
219+
"root.txt"
220+
];
221+
assertArrayIncludes<string>(names, expectedNames);
150222
});

where.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getLikeRegExp } from "./like.ts";
12
import { IDirEntry, IWhereClause, IWhereCondition } from "./types.ts";
23

34
export function where(entry: IDirEntry, where: IWhereClause | null): boolean {
@@ -75,7 +76,7 @@ function meet(entry: IDirEntry, condition: IWhereCondition): boolean {
7576
"LessThan": null,
7677
"Equal": equalString,
7778
"Different": differentString,
78-
"Like": null,
79+
"Like": likeString,
7980
};
8081

8182
const operation = operations[op];
@@ -125,3 +126,7 @@ function equalString(left: string | undefined, right: string): boolean {
125126
function differentString(left: string | undefined, right: string): boolean {
126127
return typeof left !== "undefined" && left !== right;
127128
}
129+
130+
function likeString(left: string | undefined, right: string): boolean {
131+
return typeof left !== "undefined" && left.match( getLikeRegExp(right) ) != null;
132+
}

0 commit comments

Comments
 (0)