Skip to content

Commit 77e88c6

Browse files
authored
Add it.Apply (#64)
1 parent 28008ed commit 77e88c6

18 files changed

+330
-9
lines changed

docs-eval/apply.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
title: Apply
3+
nav_order: 90
4+
parent: Examples
5+
layout: default
6+
---
7+
8+
<details open markdown="block">
9+
<summary>
10+
Table of contents
11+
</summary>
12+
{: .text-delta }
13+
1. TOC
14+
{:toc}
15+
</details>
16+
17+
```ts eval --replacePrintedInput=../src,sql-select-ts
18+
import { table, dsql as sql, select } from "../src";
19+
import { SelectStatement } from "../src/classes/select-statement";
20+
```
21+
22+
# Apply
23+
24+
Allows to use a helper function but still keep method chaining.
25+
26+
```ts eval --yield=sql
27+
// It expects a select statement that has selected a "sector" field,
28+
// which will be used as the "group by"
29+
const groupSortLimit = (query: SelectStatement<never, "sector">) =>
30+
query
31+
.groupBy((f) => f.sector)
32+
.orderBy((_f) => sql`count() DESC`)
33+
.limit(250);
34+
35+
const sector_stats = table(["id", "sector", "price"], "sector_stats");
36+
37+
yield select(/* fields: */ ["sector"], /* from: */ sector_stats)
38+
.apply(groupSortLimit)
39+
.stringify();
40+
```

docs/api/classes/compound.ts.md

+12
Original file line numberDiff line numberDiff line change
@@ -337,3 +337,15 @@ stringify: () => string;
337337
```
338338

339339
Added in v0.0.0
340+
341+
### apply (property)
342+
343+
**Signature**
344+
345+
```ts
346+
apply: <Ret extends TableOrSubquery<any, any, any, any> = never>(
347+
fn: (it: this) => Ret
348+
) => Ret;
349+
```
350+
351+
Added in v1.1.1

docs/api/classes/joined.ts.md

+12
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,18 @@ joinCompound: <
289289
290290
Added in v0.0.0
291291
292+
### apply (property)
293+
294+
**Signature**
295+
296+
```ts
297+
apply: <Ret extends TableOrSubquery<any, any, any, any> = never>(
298+
fn: (it: this) => Ret
299+
) => Ret;
300+
```
301+
302+
Added in v1.1.1
303+
292304
## JoinedFactory (class)
293305
294306
Constructor for join queries.

docs/api/classes/select-statement.ts.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ select: <
9191
f:
9292
| readonly SubSelection[]
9393
| ((
94-
f: Record<Selection | Scope, SafeString> & NoSelectFieldsCompileError
94+
f: Record<Selection, SafeString> & NoSelectFieldsCompileError
9595
) => Record<NewSelection, SafeString>)
9696
) => SelectStatement<Selection, NewSelection | SubSelection>;
9797
```
@@ -441,6 +441,18 @@ joinCompound: <
441441
442442
Added in v0.0.0
443443
444+
### apply (property)
445+
446+
**Signature**
447+
448+
```ts
449+
apply: <Ret extends TableOrSubquery<any, any, any, any> = never>(
450+
fn: (it: this) => Ret
451+
) => Ret;
452+
```
453+
454+
Added in v1.1.1
455+
444456
### stringify (property)
445457
446458
**Signature**

docs/api/classes/stringified-select-statement.ts.md

+12
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,18 @@ joinCompound: <
294294

295295
Added in v0.0.3
296296

297+
### apply (property)
298+
299+
**Signature**
300+
301+
```ts
302+
apply: <Ret extends TableOrSubquery<any, any, any, any> = never>(
303+
fn: (it: this) => Ret
304+
) => Ret;
305+
```
306+
307+
Added in v1.1.1
308+
297309
### stringify (property)
298310
299311
**Signature**

docs/api/classes/table.ts.md

+12
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,15 @@ joinCompound: <Selection2 extends string, Alias2 extends string>(
287287
```
288288
289289
Added in v0.0.0
290+
291+
### apply (property)
292+
293+
**Signature**
294+
295+
```ts
296+
apply: <Ret extends TableOrSubquery<any, any, any, any> = never>(
297+
fn: (it: this) => Ret
298+
) => Ret;
299+
```
300+
301+
Added in v1.1.1

docs/examples/apply.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: Apply
3+
nav_order: 90
4+
parent: Examples
5+
layout: default
6+
---
7+
8+
<details open markdown="block">
9+
<summary>
10+
Table of contents
11+
</summary>
12+
{: .text-delta }
13+
1. TOC
14+
{:toc}
15+
</details>
16+
17+
```ts
18+
import { table, dsql as sql, select } from "sql-select-ts";
19+
import { SelectStatement } from "sql-select-ts/classes/select-statement";
20+
```
21+
22+
# Apply
23+
24+
Allows to use a helper function but still keep method chaining.
25+
26+
```ts
27+
// It expects a select statement that has selected a "sector" field,
28+
// which will be used as the "group by"
29+
const groupSortLimit = (query: SelectStatement<never, "sector">) =>
30+
query
31+
.groupBy((f) => f.sector)
32+
.orderBy((_f) => sql`count() DESC`)
33+
.limit(250);
34+
35+
const sector_stats = table(["id", "sector", "price"], "sector_stats");
36+
37+
select(/* fields: */ ["sector"], /* from: */ sector_stats)
38+
.apply(groupSortLimit)
39+
.stringify();
40+
```
41+
42+
```sql
43+
SELECT
44+
`sector` AS `sector`
45+
FROM
46+
`sector_stats`
47+
GROUP BY
48+
`sector`
49+
ORDER BY
50+
count() DESC
51+
LIMIT
52+
250
53+
```

src/classes/compound.ts

+7
Original file line numberDiff line numberDiff line change
@@ -453,4 +453,11 @@ export class Compound<Scope extends string, Selection extends string> {
453453
* @since 0.0.0
454454
*/
455455
public stringify = (): string => printCompound(this);
456+
457+
/**
458+
* @since 1.1.1
459+
*/
460+
public apply = <Ret extends TableOrSubquery<any, any, any, any> = never>(
461+
fn: (it: this) => Ret
462+
): Ret => fn(this);
456463
}

src/classes/joined.ts

+7
Original file line numberDiff line numberDiff line change
@@ -417,4 +417,11 @@ export class Joined<
417417
operator,
418418
}
419419
);
420+
421+
/**
422+
* @since 1.1.1
423+
*/
424+
public apply = <Ret extends TableOrSubquery<any, any, any, any> = never>(
425+
fn: (it: this) => Ret
426+
): Ret => fn(this);
420427
}

src/classes/select-statement.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,7 @@ export class SelectStatement<Scope extends string, Selection extends string> {
256256
f:
257257
| ReadonlyArray<SubSelection>
258258
| ((
259-
f: Record<Selection | Scope, SafeString> &
260-
NoSelectFieldsCompileError
259+
f: Record<Selection, SafeString> & NoSelectFieldsCompileError
261260
) => Record<NewSelection, SafeString>)
262261
): SelectStatement<Selection, NewSelection | SubSelection> =>
263262
SelectStatement.__fromTableOrSubquery(this, [
@@ -636,6 +635,13 @@ export class SelectStatement<Scope extends string, Selection extends string> {
636635
}
637636
);
638637

638+
/**
639+
* @since 1.1.1
640+
*/
641+
public apply = <Ret extends TableOrSubquery<any, any, any, any> = never>(
642+
fn: (it: this) => Ret
643+
): Ret => fn(this);
644+
639645
/**
640646
* @since 0.0.0
641647
*/

src/classes/stringified-select-statement.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* @since 0.0.3
66
*/
77
import { SafeString } from "../safe-string";
8-
import { NoSelectFieldsCompileError } from "../types";
8+
import { NoSelectFieldsCompileError, TableOrSubquery } from "../types";
99
import { Compound } from "./compound";
1010
import { Joined, JoinedFactory } from "./joined";
1111
import { SelectStatement } from "./select-statement";
@@ -332,6 +332,13 @@ export class StringifiedSelectStatement<Selection extends string> {
332332
}
333333
);
334334

335+
/**
336+
* @since 1.1.1
337+
*/
338+
public apply = <Ret extends TableOrSubquery<any, any, any, any> = never>(
339+
fn: (it: this) => Ret
340+
): Ret => fn(this);
341+
335342
/**
336343
* @since 0.0.3
337344
*/

src/classes/table.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import { consumeRecordCallback } from "../consume-fields";
1010
import { AliasedRows, StarSymbol } from "../data-wrappers";
1111
import { SafeString } from "../safe-string";
12-
import { NoSelectFieldsCompileError } from "../types";
12+
import { NoSelectFieldsCompileError, TableOrSubquery } from "../types";
1313
import { Compound } from "./compound";
1414
import { Joined, JoinedFactory } from "./joined";
1515
import { SelectStatement } from "./select-statement";
@@ -338,4 +338,11 @@ export class Table<Selection extends string, Alias extends string> {
338338
operator,
339339
}
340340
);
341+
342+
/**
343+
* @since 1.1.1
344+
*/
345+
public apply = <Ret extends TableOrSubquery<any, any, any, any> = never>(
346+
fn: (it: this) => Ret
347+
): Ret => fn(this);
341348
}

tests/sqlite-suite/select1.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,28 @@ describe("sqlite select1", () => {
4646
await run(`INSERT INTO t6 VALUES('c','2');`);
4747
await run(`INSERT INTO t6 VALUES('d','3');`);
4848
});
49+
50+
it("apply type checks", async () => {
51+
const q1 = test1.selectStar();
52+
unionAll([q1, q1, q1])
53+
.apply((it) => it.select(["f1"]))
54+
.select((f) => ({
55+
//@ts-expect-error
56+
b: f.f2,
57+
}))
58+
.stringify();
59+
expect(1).toBe(1);
60+
61+
unionAll([q1, q1, q1])
62+
.select(["f1"])
63+
.select((f) => ({
64+
//@ts-expect-error
65+
b: f.f2,
66+
}))
67+
.stringify();
68+
expect(1).toBe(1);
69+
});
70+
4971
it("select0", async () => {
5072
const q = test1
5173
.select((f) => ({
@@ -1264,6 +1286,7 @@ describe("sqlite select1", () => {
12641286
.select((f) => ({
12651287
a: f.f1,
12661288
b: f.f2,
1289+
//@ts-expect-error
12671290
c: f["it.r1"],
12681291
}))
12691292
.stringify();

tests/unit/union.test.ts renamed to tests/unit/compound.test.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { table, unionAll } from "../../src";
22
import * as NEA from "fp-ts/lib/NonEmptyArray";
33
const cols = ["a", "b"] as const;
4-
describe("table", () => {
4+
describe("compound unit", () => {
55
it("works", () => {
66
const q1 = table(cols, "a").selectStar();
77
const q2 = table(cols, "b").selectStar();
@@ -30,4 +30,24 @@ describe("table", () => {
3030
`"SELECT * FROM \`a\` UNION ALL SELECT * FROM \`a\` UNION ALL SELECT * FROM \`a\`"`
3131
);
3232
});
33+
34+
it("apply", () => {
35+
const q1 = table(cols, "a").selectStar();
36+
const u = unionAll([q1, q1, q1]).apply((it) => it.select(["a"]));
37+
expect(u.stringify()).toMatchInlineSnapshot(
38+
`"SELECT \`a\` AS \`a\` FROM (SELECT * FROM \`a\` UNION ALL SELECT * FROM \`a\` UNION ALL SELECT * FROM \`a\`)"`
39+
);
40+
});
41+
42+
it("apply type checks", () => {
43+
const q1 = table(cols, "a").selectStar();
44+
unionAll([q1, q1, q1])
45+
.apply((it) => it.select(["a"]))
46+
.select((f) => ({
47+
b:
48+
// @ts-expect-error
49+
f.b,
50+
}));
51+
expect(1).toBe(1);
52+
});
3353
});

tests/unit/join.test.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { dsql, table } from "../../src";
22

3+
const cols = ["a", "b"] as const;
34
describe("table", () => {
45
it("columns readonly", () => {
5-
const cols = ["a", "b"] as const;
66
const q = table(cols, "t").select((_f) => ({ a: dsql(1) }));
77

88
q.joinSelect("m", "LEFT", "q2", q).on((f) => [
@@ -23,4 +23,26 @@ describe("table", () => {
2323

2424
expect(1).toBe(1);
2525
});
26+
27+
it("apply", () => {
28+
const t = table(cols, "a");
29+
const q = t
30+
.commaJoinSelect("a2", t.selectStar())
31+
.apply((it) => it.select(["a"]));
32+
expect(q.stringify()).toMatchInlineSnapshot(
33+
`"SELECT \`a\` AS \`a\` FROM \`a\`, (SELECT * FROM \`a\`) AS \`a2\`"`
34+
);
35+
});
36+
37+
it("apply type checks", () => {
38+
table(cols, "a")
39+
.apply((it) => it.select(["a"]))
40+
.select((f) => ({
41+
b:
42+
//@ts-expect-error
43+
f.b,
44+
}));
45+
46+
expect(1).toBe(1);
47+
});
2648
});

0 commit comments

Comments
 (0)