Skip to content

Commit

Permalink
Merge pull request #15 from FSou1/feature/9-sql-like
Browse files Browse the repository at this point in the history
Feature/9 sql like
  • Loading branch information
FSou1 authored Apr 22, 2021
2 parents 21116ab + 941f230 commit 245a154
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 10 deletions.
10 changes: 2 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export interface IDirEntry {

### Operators

The list of supported operators: `>`, `<`, `=`, `<>`.
The list of supported operators: `>`, `<`, `=`, `<>`, `like`.

### Supported

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

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

### TODO

`select * from root where name like '%txt'`

`select * from root where name like '%txt%'`

`select * from root where name like 'txt%'`
`select * from root where name like '%.txt'`
7 changes: 7 additions & 0 deletions like.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function getLikeRegExp(input: string): RegExp {
const pattern = input
.replaceAll(".", "\\.")
.replaceAll("%", ".*?");

return new RegExp("^" + pattern + "$");
}
91 changes: 91 additions & 0 deletions like_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { assert, assertEquals } from "./deps.ts";
import { getLikeRegExp } from "./like.ts";

Deno.test("where name like 'abc.txt'", () => {
const regexp = getLikeRegExp("abc.txt");

/* Match */
assert("abc.txt".match(regexp));

/* Does not match */
assertEquals("a.txt".match(regexp), null);
assertEquals("abc_d.txt".match(regexp), null);
assertEquals("abc.tx".match(regexp), null);
});

Deno.test("where name like '%.txt'", () => {
const regexp = getLikeRegExp("%.txt");

/* Match */
assert("abc.txt".match(regexp));
assert("c.txt".match(regexp));
assert("ab_c.txt".match(regexp));
assert("ab_-\/*+ddc.txt".match(regexp));

/* Does not match */
assertEquals("abc.bin".match(regexp), null);
assertEquals(".txn".match(regexp), null);
assertEquals("abc_txt".match(regexp), null);
assertEquals("abc.!txt".match(regexp), null);
assertEquals("abc.txt_bin".match(regexp), null);
});

Deno.test("where name like '%.txt%'", () => {
const regexp = getLikeRegExp("%.txt%");

/* Match */
assert("abc.txt".match(regexp));
assert("c.txt".match(regexp));
assert("ab_c.txt".match(regexp));
assert("ab_-\/*+ddc.txt".match(regexp));

/* Does not match */
assertEquals("abc.bin".match(regexp), null);
assertEquals(".txn".match(regexp), null);
assertEquals("abc_txt".match(regexp), null);
});

Deno.test("where name like 'ab%txt'", () => {
const regexp = getLikeRegExp("ab%txt");

/* Match */
assert("abc.txt".match(regexp));
assert("abdef_.txt".match(regexp));
assert("ab_c.txt".match(regexp));
assert("ab_-\/*+ddc.txt".match(regexp));

/* Does not match */
assertEquals("abc.bin".match(regexp), null);
assertEquals("abc".match(regexp), null);
assertEquals("d_abc.txt".match(regexp), null);
assertEquals("abc.txt.".match(regexp), null);
assertEquals("abc.txt!".match(regexp), null);
});

Deno.test("where name like 'abc.%'", () => {
const regexp = getLikeRegExp("abc.%");

/* Match */
assert("abc.txt".match(regexp));
assert("abc.bin".match(regexp));
assert("abc.".match(regexp));

/* Does not match */
assertEquals("abc".match(regexp), null);
assertEquals("d".match(regexp), null);
assertEquals("abc?.".match(regexp), null);
});

Deno.test("where name like '%.%'", () => {
const regexp = getLikeRegExp("%.%");

/* Match */
assert("abc.txt".match(regexp));
assert("abc.bin".match(regexp));
assert("abc.".match(regexp));
assert(".".match(regexp));
assert(".txt".match(regexp));

/* Does not match */
assertEquals("abc".match(regexp), null);
});
74 changes: 73 additions & 1 deletion mod_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { fsselect } from "./mod.ts";

Deno.test("if 'select * from .' works", async () => {
const result = await fsselect("select * from .");
assert(result.length === 18);
assert(result.length === 20);
});

Deno.test("if 'select * from root' works", async () => {
Expand Down Expand Up @@ -147,4 +147,76 @@ Deno.test("if select * from root where name <> 'root.txt' works", async () => {
"test_folder_with_folder",
];
assertArrayIncludes<string>(names, expectedNames);
});

Deno.test("if select * from root where name like 'test_%' works", async () => {
const result = await fsselect("select * from root where name like 'test_%'");
assert(result.length === 3);

const names = result.map((i) => i.name as string);
const expectedNames = [
"test_folder_with_file",
"test_folder_with_files",
"test_folder_with_folder",
];
assertArrayIncludes<string>(names, expectedNames);
});

Deno.test("if select * from root where name like '%folder%' works", async () => {
const result = await fsselect("select * from root where name like '%folder%'");
assert(result.length === 3);

const names = result.map((i) => i.name as string);
const expectedNames = [
"test_folder_with_file",
"test_folder_with_files",
"test_folder_with_folder",
];
assertArrayIncludes<string>(names, expectedNames);
});

Deno.test("if select * from root where name like '%.txt' works", async () => {
const result = await fsselect("select * from root where name like '%.txt'");
assert(result.length === 1);

const names = result.map((i) => i.name as string);
const expectedNames = [
"root.txt"
];
assertArrayIncludes<string>(names, expectedNames);
});

Deno.test("if select * from root where name like '%with_file%' works", async () => {
const result = await fsselect("select * from root where name like '%with_file%'");
assert(result.length === 2);

const names = result.map((i) => i.name as string);
const expectedNames = [
"test_folder_with_file",
"test_folder_with_files",
];
assertArrayIncludes<string>(names, expectedNames);
});

Deno.test("if select * from root where name like 'some' does not return entries", async () => {
const result = await fsselect("select * from root where name like 'some'");
assert(result.length === 0);

const names = result.map((i) => i.name as string);
const expectedNames: string[] = [];
assertArrayIncludes<string>(names, expectedNames);
});

Deno.test("if select * from root where name like '%%' works", async () => {
const result = await fsselect("select * from root where name like '%%'");
assert(result.length === 4);

const names = result.map((i) => i.name as string);
const expectedNames = [
"test_folder_with_file",
"test_folder_with_files",
"test_folder_with_folder",
"root.txt"
];
assertArrayIncludes<string>(names, expectedNames);
});
7 changes: 6 additions & 1 deletion where.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getLikeRegExp } from "./like.ts";
import { IDirEntry, IWhereClause, IWhereCondition } from "./types.ts";

export function where(entry: IDirEntry, where: IWhereClause | null): boolean {
Expand Down Expand Up @@ -75,7 +76,7 @@ function meet(entry: IDirEntry, condition: IWhereCondition): boolean {
"LessThan": null,
"Equal": equalString,
"Different": differentString,
"Like": null,
"Like": likeString,
};

const operation = operations[op];
Expand Down Expand Up @@ -125,3 +126,7 @@ function equalString(left: string | undefined, right: string): boolean {
function differentString(left: string | undefined, right: string): boolean {
return typeof left !== "undefined" && left !== right;
}

function likeString(left: string | undefined, right: string): boolean {
return typeof left !== "undefined" && left.match( getLikeRegExp(right) ) != null;
}

0 comments on commit 245a154

Please sign in to comment.