Skip to content

Commit 73083c0

Browse files
committed
Implementing feedback.
1 parent c3023ab commit 73083c0

File tree

6 files changed

+119
-67
lines changed

6 files changed

+119
-67
lines changed

src/content/changelogs/d1.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ productLink: "/d1/"
55
productArea: Developer platform
66
productAreaLink: /workers/platform/changelog/platform/
77
entries:
8-
- publish_date: "2024-11-18"
8+
- publish_date: "2024-11-01"
99
title: Support for multiple queries in a single prepared statement
1010
description: |-
1111
You can now have multiple queries in a single prepared statement when using `db.prepare`. To use this feature, separate each query with a semi-colon. Prepared statements with multiple queries only returns the results of the last query, even though all queries are executed. Additionally, you can only bind parameters to the last query in the prepared statement.

src/content/docs/d1/get-started.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,5 +532,5 @@ In this tutorial, you have:
532532
If you have any feature requests or notice any bugs, share your feedback directly with the Cloudflare team by joining the [Cloudflare Developers community on Discord](https://discord.cloudflare.com).
533533

534534
- See supported [Wrangler commands for D1](/workers/wrangler/commands/#d1).
535-
- Learn how to use the [D1 Worker Binding API](/d1/worker-api/) within your Worker.
535+
- Learn how to use the [D1 Worker Binding API](/d1/worker-api/) within your Worker, and test them from the [API playground](/d1/worker-api/#api-playground).
536536
- Explore [community projects built on D1](/d1/reference/community-projects/).

src/content/docs/d1/worker-api/index.mdx

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ sidebar:
77

88
import { DirectoryListing, Details, Steps } from "~/components";
99

10-
You can execute queries on your D1 database through SQL query statements. To do this, you need to perform the following steps:
10+
You can execute SQL queries on your D1 database from a Worker using the Worker Binding API. To do this, you can perform the following steps:
1111

1212
1. [Prepare a statement](/d1/worker-api/prepare-a-statement).
1313
2. [Run the prepared statement](/d1/worker-api/run-a-statement).
@@ -17,9 +17,9 @@ Refer to the relevant sections for the API documentation.
1717

1818
## Typescript support
1919

20-
D1 Worker Bindings API is fully-typed via the `@cloudflare/workers-types` package, and also supports [generic types](https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-types) as part of its TypeScript API. A generic type allows you to provide an optional _type parameter_ so that a function understands the type of the data it is handling.
20+
D1 Worker Bindings API is fully-typed via the [`@cloudflare/workers-types`](/workers/languages/typescript/#typescript) package, and also supports [generic types](https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-types) as part of its TypeScript API. A generic type allows you to provide an optional _type parameter_ so that a function understands the type of the data it is handling.
2121

22-
When using the [query statement methods](#query-statement-methods) `stmt.run()`, `stmt.raw()` and `stmt.first()`, you can provide a type representing each database row. D1's API will [return the result object](#return-object) with the correct type.
22+
When using the [query statement methods](/d1/worker-api/run-a-statement) `stmt.run()`, `stmt.raw()` and `stmt.first()`, you can provide a type representing each database row. D1's API will [return the result object](#return-object) with the correct type.
2323

2424
For example, providing an `OrderRow` type as a type parameter to `stmt.run()` will return a typed `Array<OrderRow>` object instead of the default `Record<string, unknown>` type:
2525

@@ -56,40 +56,55 @@ Replace the contents of your `index.js` file with the below to view the effect o
5656
<Details header="index.js" open={false}>
5757
```js
5858
export default {
59-
async fetch(request, env) {
60-
const { pathname } = new URL(request.url);
61-
62-
const companyName1 = `Bs Beverages`;
63-
const companyName2 = `Around the Horn`;
64-
const stmt = env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`);
65-
66-
if (pathname === `/RUN`){
67-
const returnValue = await stmt.bind(companyName1).run()
68-
return Response.json(returnValue);
69-
70-
} else if (pathname === `/RAW`){
71-
const returnValue = await stmt.bind(companyName1).raw();
72-
return Response.json(returnValue);
73-
74-
} else if (pathname === `/FIRST`){
75-
const returnValue = await stmt.bind(companyName1).first();
76-
return Response.json(returnValue);
77-
78-
} else if (pathname === `/BATCH`) {
79-
const batchResult = await env.DB.batch([
80-
stmt.bind(companyName1),
81-
stmt.bind(companyName2)
82-
]);
83-
// const returnValue = await stmt.run();
84-
return Response.json(batchResult);
85-
}
86-
87-
return new Response(
88-
`Welcome to the D1 API Playground!
89-
\nChange the URL to test the methods inside your index.js file.`,
90-
);
91-
},
92-
};
59+
async fetch(request, env) {
60+
const { pathname } = new URL(request.url);
61+
62+
// if (pathname === "/api/beverages") {
63+
// // If you did not use `DB` as your binding name, change it here
64+
// const { results } = await env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?",).bind("Bs Beverages").all();
65+
// return Response.json(results);
66+
// }
67+
68+
const companyName1 = `Bs Beverages`;
69+
const companyName2 = `Around the Horn`;
70+
const stmt = env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`);
71+
const stmtMulti = env.DB.prepare(`SELECT * FROM Customers; SELECT * FROM Customers WHERE CompanyName = ?`);
72+
73+
if (pathname === `/RUN`){
74+
const returnValue = await stmt.bind(companyName1).run();
75+
return Response.json(returnValue);
76+
77+
} else if (pathname === `/RAW`){
78+
const returnValue = await stmt.bind(companyName1).raw();
79+
return Response.json(returnValue);
80+
81+
} else if (pathname === `/FIRST`){
82+
const returnValue = await stmt.bind(companyName1).first();
83+
return Response.json(returnValue);
84+
85+
} else if (pathname === `/BATCH`) {
86+
const batchResult = await env.DB.batch([
87+
stmt.bind(companyName1),
88+
stmt.bind(companyName2)
89+
]);
90+
// const returnValue = await stmt.run();
91+
return Response.json(batchResult);
92+
93+
} else if (pathname === `/RUNMULTI`){
94+
const returnValue = await stmtMulti.bind(companyName1).run();
95+
return Response.json(returnValue);
96+
97+
} else if (pathname === `/EXEC`){
98+
const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`);
99+
return Response.json(returnValue);
100+
}
101+
102+
return new Response(
103+
`Welcome to the D1 API Playground!
104+
\nChange the URL to test the various methods inside your index.js file.`,
105+
);
106+
},
107+
};
93108

94109
```
95110
</Details>

src/content/docs/d1/worker-api/prepare-a-statement.mdx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bin
3131

3232
#### Guidance
3333

34-
- You can pass multiple queries into a single `.prepare()` statement. Simply delineate each query with a semi-colon.
35-
- The statement only returns the results of the last query, even though all queries are executed.
36-
- You can only bind parameters to the last query.
37-
```js
38-
const stmt = db.prepare(`SELECT * FROM users WHERE name = "Anthony"; SELECT * FROM users WHERE name = ?1`).bind("Joe")
39-
```
4034
- D1 follows the [SQLite convention](https://www.sqlite.org/lang_expr.html#varparam) for prepared statements parameter binding. Currently, D1 only supports Ordered (`?NNNN`) and Anonymous (`?`) parameters. In the future, D1 will support named parameters as well.
4135

4236
| Syntax | Type | Description |
@@ -64,6 +58,13 @@ const stmt = env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?").bin
6458
.bind(1, "Alfreds Futterkiste");
6559
```
6660

61+
- You can pass multiple queries into a single `.prepare()` statement. Simply delineate each query with a semi-colon.
62+
- The statement only returns the results of the last query, even though all queries are executed.
63+
- You can only bind parameters to the last query.
64+
```js
65+
const stmt = db.prepare(`SELECT * FROM users WHERE name = "Anthony"; SELECT * FROM users WHERE name = ?1`).bind("Joe")
66+
```
67+
6768
## Static statements
6869

6970
D1 API supports static statements. Static statements are SQL statements where the variables have been hard coded. When writing a static statement, you manually type the variable within the statement string.

src/content/docs/d1/worker-api/return-object.mdx

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
---
2-
title: Return object
2+
title: Return objects
33
pcx_content_type: concept
44
sidebar:
55
order: 3
66
---
77

8-
The methods `stmt.run()`, `db.exec()`, and `db.batch()` return a typed `D1Result` object for each query statement. This object contains:
8+
Some D1 Worker Binding APIs return a typed object.
9+
10+
| D1 Worker Binding API | Return object |
11+
| ------------------------- | ------------- |
12+
| `stmt.run()`, `db.batch()`| `D1Result` |
13+
| `db.exec()` | `D1ExecResult`|
14+
15+
## D1Result
16+
17+
The methods `stmt.run()` and `db.batch()` return a typed `D1Result` object for each query statement. This object contains:
918

1019
- The success status
1120
- A meta object with the internal duration of the operation in milliseconds
@@ -28,7 +37,7 @@ The methods `stmt.run()`, `db.exec()`, and `db.batch()` return a typed `D1Result
2837
}
2938
```
3039

31-
## Example:
40+
### Example
3241

3342
```js
3443
const someVariable = `Bs Beverages`;
@@ -62,4 +71,31 @@ return Response.json(result)
6271
}
6372
]
6473
}
74+
```
75+
76+
## D1ExecResult
77+
78+
The method `db.exec()` returns a typed `D1ExecResult` object for each query statement. This object contains:
79+
80+
- The number of executed queries
81+
- The duration of the operation in milliseconds
82+
83+
```js
84+
{
85+
"count": number, // the number of executed queries
86+
"duration": number // the duration of the operation, in milliseconds
87+
}
88+
```
89+
90+
### Example
91+
92+
```js
93+
const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`);
94+
return Response.json(returnValue);
95+
```
96+
```js output
97+
{
98+
"count": 1,
99+
"duration": 1
100+
}
65101
```

src/content/docs/d1/worker-api/run-a-statement.mdx

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Run a prepared statement
2+
title: Run a statement
33
pcx_content_type: concept
44
sidebar:
55
order: 2
@@ -25,9 +25,9 @@ const returnValue = await stmt.run();
2525

2626
#### Return value
2727

28-
- <code>returnValue</code>: <Type text="Object"/>
28+
- <code>D1Result</code>: <Type text="Object"/>
2929
- An object containing the success status, a meta object, and an array of objects containing the query results.
30-
- For more information on the returned object, refer to [Return objects](/d1/worker-api/return-object).
30+
- For more information on the object, refer to [`D1Result`](/d1/worker-api/return-object/d1result).
3131

3232
<Details header="Example of return values" open = {false}>
3333
```js
@@ -294,8 +294,8 @@ const batchResult = await env.DB.batch([
294294
#### Return values
295295

296296
- <code>results</code>: <Type text="Array"/>
297-
- An array of objects containing the results of the `.db.prepare()` statements. Each object is in the array position corresponding to the array position of the initial `db.prepare()` statement within the `statementArray`.
298-
- For more information on the returned object, refer to [Return objects](/d1/worker-api/return-object).
297+
- An array of `D1Result` objects containing the results of the `.db.prepare()` statements. Each object is in the array position corresponding to the array position of the initial `db.prepare()` statement within the `statementArray`.
298+
- Refer to [`D1Result`](/d1/worker-api/return-object/d1result) for more information about this object.
299299

300300
<Details header="Example of return values" open={false}>
301301

@@ -388,32 +388,33 @@ console.log(stmt[1].results);
388388

389389
### `db.exec()`
390390

391-
Executes one or more queries directly without prepared statements or parameters binding.
391+
Executes one or more queries directly without prepared statements or parameter bindings.
392392

393393
```js
394-
const migration = await fetch("/migration.sql");
395-
const out = await db.exec(migration.text());
394+
const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`);
396395
```
397396

398397
#### Parameters
399398

400-
-
399+
- <code>queryString</code>: <Type text="String"/> <MetaInfo text="Required"/>
400+
- The SQL query statement without parameter binding.
401401

402402
#### Return values
403403

404-
- <code>queryResult</code>: <Type text="Any"/>
405-
- Result of the query.
404+
- <code>D1ExecResult</code>: <Type text="Object"/>
405+
- The `count` property contains the number of executed queries.
406+
- The `duration` property contains the duration of operation in milliseconds.
407+
- Refer to [`D1ExecResult`](/d1/worker-api/return-object/#d1execresult) for more information.
406408

407409
<Details header="Example of return values" open={false}>
408410
```js
409-
const migration = await fetch("/migration.sql");
410-
const out = await db.exec(migration.text());
411-
console.log(out);
411+
const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`);
412+
return Response.json(returnValue);
412413
```
413414
```js output
414415
{
415-
count: 80,
416-
duration: 76
416+
"count": 1,
417+
"duration": 1
417418
}
418419
```
419420
</Details>
@@ -445,9 +446,8 @@ return new Response(dump, {
445446

446447
#### Parameters
447448

448-
-
449+
- None.
449450

450451
#### Return values
451452

452-
-
453-
453+
- None.

0 commit comments

Comments
 (0)