Skip to content

Commit bdc60d0

Browse files
committed
Finish subquery
1 parent 82c6f1e commit bdc60d0

File tree

5 files changed

+69
-97
lines changed

5 files changed

+69
-97
lines changed

biome.json

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
{
2-
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3-
"vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false },
4-
"files": { "ignoreUnknown": false, "ignore": ["dist", "docs/site"] },
5-
"formatter": {
6-
"enabled": true,
7-
"useEditorconfig": true,
8-
"formatWithErrors": false,
9-
"indentStyle": "space",
10-
"indentWidth": 2,
11-
"lineEnding": "lf",
12-
"lineWidth": 120,
13-
"attributePosition": "auto",
14-
"bracketSpacing": true
15-
},
16-
"organizeImports": { "enabled": true },
17-
"linter": {
18-
"enabled": true,
19-
"rules": { "recommended": false }
20-
},
21-
"javascript": {
22-
"formatter": {
23-
"jsxQuoteStyle": "double",
24-
"quoteProperties": "asNeeded",
25-
"trailingCommas": "es5",
26-
"semicolons": "asNeeded",
27-
"arrowParentheses": "always",
28-
"bracketSameLine": false,
29-
"quoteStyle": "single",
30-
"attributePosition": "auto",
31-
"bracketSpacing": true
32-
}
33-
}
2+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3+
"vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false },
4+
"files": { "ignoreUnknown": false, "ignore": ["dist", "docs/site"] },
5+
"formatter": {
6+
"enabled": true,
7+
"useEditorconfig": true,
8+
"formatWithErrors": false,
9+
"indentStyle": "space",
10+
"indentWidth": 2,
11+
"lineEnding": "lf",
12+
"lineWidth": 120,
13+
"attributePosition": "auto",
14+
"bracketSpacing": true
15+
},
16+
"organizeImports": { "enabled": true },
17+
"linter": {
18+
"enabled": true,
19+
"rules": { "recommended": false }
20+
},
21+
"javascript": {
22+
"formatter": {
23+
"jsxQuoteStyle": "double",
24+
"quoteProperties": "asNeeded",
25+
"trailingCommas": "es5",
26+
"semicolons": "asNeeded",
27+
"arrowParentheses": "always",
28+
"bracketSameLine": false,
29+
"quoteStyle": "single",
30+
"attributePosition": "auto",
31+
"bracketSpacing": true
32+
}
33+
}
3434
}

docs/.vitepress/config.mts

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,56 @@
1-
import {defineConfig} from 'vitepress'
1+
import { defineConfig } from 'vitepress'
22

33
// https://vitepress.dev/reference/site-config
44
export default defineConfig({
5-
title: "workers-qb",
6-
text: "Zero dependencies Query Builder for Cloudflare Workers",
5+
title: 'workers-qb',
6+
text: 'Zero dependencies Query Builder for Cloudflare Workers',
77
cleanUrls: true,
8-
head: [['link', {rel: 'icon', type: "image/png", href: 'https://raw.githubusercontent.com/G4brym/workers-qb/refs/heads/main/docs/assets/logo-icon.png'}]],
8+
head: [
9+
[
10+
'link',
11+
{
12+
rel: 'icon',
13+
type: 'image/png',
14+
href: 'https://raw.githubusercontent.com/G4brym/workers-qb/refs/heads/main/docs/assets/logo-icon.png',
15+
},
16+
],
17+
],
918
themeConfig: {
1019
// https://vitepress.dev/reference/default-theme-config
1120
logo: 'https://raw.githubusercontent.com/G4brym/workers-qb/refs/heads/main/docs/assets/logo-icon.png',
1221
outline: [2, 3],
1322
nav: [
14-
{text: 'Home', link: '/'},
15-
{text: 'Docs', link: '/introduction'}
23+
{ text: 'Home', link: '/' },
24+
{ text: 'Docs', link: '/introduction' },
1625
],
1726
sidebar: [
1827
{
1928
text: 'Getting Started',
2029
items: [
21-
{text: 'Introduction', link: '/introduction'},
22-
{text: 'Basic Queries', link: '/basic-queries'},
23-
{text: 'Advanced Queries', link: '/advanced-queries'},
24-
{text: 'Migrations', link: '/migrations'},
25-
{text: 'Type Checking', link: '/type-check'},
26-
]
30+
{ text: 'Introduction', link: '/introduction' },
31+
{ text: 'Basic Queries', link: '/basic-queries' },
32+
{ text: 'Advanced Queries', link: '/advanced-queries' },
33+
{ text: 'Migrations', link: '/migrations' },
34+
{ text: 'Type Checking', link: '/type-check' },
35+
],
2736
},
2837
{
2938
text: 'Databases',
3039
items: [
31-
{text: 'D1', link: '/databases/d1'},
32-
{text: 'Durable Objects', link: '/databases/do'},
33-
{text: 'PostgreSQL', link: '/databases/postgresql'},
34-
{text: 'Bring your own', link: '/databases/byodb'},
35-
]
40+
{ text: 'D1', link: '/databases/d1' },
41+
{ text: 'Durable Objects', link: '/databases/do' },
42+
{ text: 'PostgreSQL', link: '/databases/postgresql' },
43+
{ text: 'Bring your own', link: '/databases/byodb' },
44+
],
3645
},
3746
],
3847
socialLinks: [
39-
{icon: 'github', link: 'https://github.com/G4brym/workers-qb'},
40-
{icon: 'x', link: 'https://x.com/G4brym'}
48+
{ icon: 'github', link: 'https://github.com/G4brym/workers-qb' },
49+
{ icon: 'x', link: 'https://x.com/G4brym' },
4150
],
4251
footer: {
4352
message: 'Released under the MIT License.',
44-
copyright: 'Copyright © 2024-present Gabriel Massadas'
45-
}
46-
}
53+
copyright: 'Copyright © 2024-present Gabriel Massadas',
54+
},
55+
},
4756
})

docs/advanced-queries.md

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,7 @@ console.log('User and product combinations:', userProductCombinations.results);
8989

9090
## Subqueries
9191

92-
`workers-qb` supports using subqueries within your `WHERE`, `HAVING` and `JOIN` clauses, allowing for more complex and powerful queries.
93-
You can construct a subquery in two main ways:
94-
95-
1. **Passing a `SelectBuilder` instance**: Useful when you want to build a subquery and reuse it in multiple places.
96-
2. **Using an inline function**: A concise way to define a subquery directly within the main query.
92+
`workers-qb` supports using subqueries within your `WHERE`, `HAVING` and `JOIN` clauses, allowing for more complex and powerful queries.
9793

9894
### `IN` with a Subquery
9995

@@ -122,23 +118,6 @@ console.log(tasksInActiveProjects.results);
122118
// SQL: SELECT * FROM tasks WHERE project_id IN (SELECT id FROM projects WHERE status = 'active')
123119
```
124120

125-
#### Using an inline function
126-
127-
```typescript
128-
import { D1QB } from 'workers-qb';
129-
130-
// ... (D1QB initialization) ...
131-
132-
// Main query: Get tasks that belong to active projects
133-
const tasksInActiveProjects = await qb
134-
.select('tasks')
135-
.where('project_id IN ?', (qb) => qb.select('projects').fields('id').where('status = ?', 'active'))
136-
.execute();
137-
138-
console.log(tasksInActiveProjects.results);
139-
// SQL: SELECT * FROM tasks WHERE project_id IN (SELECT id FROM projects WHERE status = 'active')
140-
```
141-
142121
### `EXISTS` with a Subquery
143122

144123
Check for the existence of rows in a subquery. This is useful for conditional filtering.

package.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@
55
"main": "./dist/index.js",
66
"module": "./dist/index.mjs",
77
"types": "./dist/index.d.ts",
8-
"files": [
9-
"dist",
10-
"LICENSE",
11-
"README.md"
12-
],
8+
"files": ["dist", "LICENSE", "README.md"],
139
"scripts": {
1410
"build": "tsup src/index.ts --format cjs,esm --dts",
1511
"lint": "npx @biomejs/biome check src/ tests/ || (npx @biomejs/biome check --write src/ tests/; exit 1)",

tests/unit/subquery.test.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,13 @@ describe('Subqueries using SelectBuilder instance', () => {
1818
expect(q.arguments).toEqual(['active'])
1919
})
2020

21-
it('column IN (subquery) - using an inline function', () => {
22-
const q = new QuerybuilderTest()
23-
.select('tasks')
24-
.where('project_id IN ?', (qb) => qb.select('projects').fields('id').where('status = ?', 'active'))
25-
.getQueryAll()
26-
27-
expect(q.query).toEqual('SELECT * FROM tasks WHERE project_id IN (SELECT id FROM projects WHERE status = ?)')
28-
expect(q.arguments).toEqual(['active'])
29-
})
30-
3121
it('EXISTS (subquery)', () => {
3222
const sub = new QuerybuilderTest().select('permissions').where('user_id = ?', 100).where('action = ?', 'edit')
3323
const q = new QuerybuilderTest().select('documents').where('EXISTS ?', sub).getQueryAll()
3424

35-
expect(q.query).toEqual('SELECT * FROM documents WHERE EXISTS (SELECT * FROM permissions WHERE user_id = ? AND action = ?)')
25+
expect(q.query).toEqual(
26+
'SELECT * FROM documents WHERE EXISTS (SELECT * FROM permissions WHERE (user_id = ?) AND (action = ?))'
27+
)
3628
expect(q.arguments).toEqual([100, 'edit'])
3729
})
3830

@@ -50,11 +42,7 @@ describe('Subqueries using SelectBuilder instance', () => {
5042
.fields('customer_id')
5143
.groupBy('customer_id')
5244
.having('SUM(total) > ?', 1000)
53-
const q = new QuerybuilderTest()
54-
.select('customers')
55-
.fields(['id', 'name'])
56-
.having('id IN ?', sub)
57-
.getQueryAll()
45+
const q = new QuerybuilderTest().select('customers').fields(['id', 'name']).having('id IN ?', sub).getQueryAll()
5846

5947
expect(q.query).toEqual(
6048
'SELECT id, name FROM customers HAVING id IN (SELECT customer_id FROM orders GROUP BY customer_id HAVING SUM(total) > ?)'

0 commit comments

Comments
 (0)