Skip to content

Commit eb5b0a9

Browse files
committed
Extend D1 docs with clarifications for one-way type conversions
Clarify the type conversion happening in D1 to avoid confusion by users. Example: cloudflare/workers-sdk#8642
1 parent 98666d5 commit eb5b0a9

File tree

1 file changed

+69
-60
lines changed

1 file changed

+69
-60
lines changed

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

Lines changed: 69 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -26,40 +26,52 @@ For example, providing an `OrderRow` type as a type parameter to [`D1PreparedSta
2626

2727
```ts
2828
// Row definition
29-
type OrderRow = {
30-
Id: string;
31-
CustomerName: string;
32-
OrderDate: number;
33-
};
29+
type OrderRow = { Id: string; CustomerName: string; OrderDate: number };
3430

3531
// Elsewhere in your application
3632
const result = await env.MY_DB.prepare(
37-
"SELECT Id, CustomerName, OrderDate FROM [Order] ORDER BY ShippedDate DESC LIMIT 100",
33+
"SELECT Id, CustomerName, OrderDate FROM [Order] ORDER BY ShippedDate DESC LIMIT 100",
3834
).run<OrderRow>();
3935
```
4036

4137
## Type conversion
4238

43-
D1 automatically converts supported JavaScript (including TypeScript) types passed as parameters via the Workers Binding API to their associated D1 types. The type conversion is as follows:
39+
D1 automatically converts supported JavaScript (including TypeScript) types passed as parameters via the Workers Binding API to their associated D1 types <sup>1</sup>.
40+
This conversion is permanent and one-way only, meaning that when reading the written values back in your code you will get the converted values and not the originally inserted values.
41+
42+
Sidenote: We recommend using [STRICT tables](https://www.sqlite.org/stricttables.html) in your SQL schema to avoid issues with mismatched types actually stored in your database compared to what your schema defines.
43+
44+
The type conversion during writes is as follows:
4445

45-
| JavaScript | D1 |
46-
| -------------------- | ---------------------------------------------------------------------------- |
47-
| null | `NULL` |
48-
| Number | `REAL` |
49-
| Number <sup>1</sup> | `INTEGER` |
50-
| String | `TEXT` |
51-
| Boolean <sup>2</sup> | `INTEGER` |
52-
| ArrayBuffer | `BLOB` |
53-
| undefined | Not supported. Queries with `undefined` values will return a `D1_TYPE_ERROR` |
46+
| JavaScript (write) | D1 | JavaScript (read) |
47+
| -------------------- | --------------------------- | ------------------ |
48+
| null | `NULL` | null |
49+
| Number | `REAL` | Number |
50+
| Number <sup>2</sup> | `INTEGER` | Number |
51+
| String | `TEXT` | String |
52+
| Boolean <sup>3</sup> | `INTEGER` | Number (`0`,`1`) |
53+
| ArrayBuffer | `BLOB` | Array <sup>4</sup> |
54+
| ArrayBuffer View | `BLOB` | Array <sup>4</sup> |
55+
| undefined | Not supported. <sup>5</sup> | - |
5456

55-
<sup>1</sup> D1 supports 64-bit signed `INTEGER` values internally, however
57+
<sup>1</sup> D1 types correspond to the underlying [SQLite
58+
types](https://www.sqlite.org/datatype3.html).
59+
60+
<sup>2</sup> D1 supports 64-bit signed `INTEGER` values internally, however
5661
[BigInts](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
5762
are not currently supported in the API yet. JavaScript integers are safe up to
5863
[`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER).
5964

60-
<sup>2</sup> Booleans will be cast to an `INTEGER` type where `1` is `TRUE` and
65+
<sup>3</sup> Booleans will be cast to an `INTEGER` type where `1` is `TRUE` and
6166
`0` is `FALSE`.
6267

68+
<sup>4</sup> `ArrayBuffer` and [`ArrayBuffer`
69+
views](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView)
70+
are converted using
71+
[`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from).
72+
73+
<sup>5</sup> Queries with `undefined` values will return a `D1_TYPE_ERROR`.
74+
6375
## API playground
6476

6577
The D1 Worker Binding API playground is an `index.js` file where you can test each of the documented Worker Binding APIs for D1. The file builds from the end-state of the [Get started](/d1/get-started/#write-queries-within-your-worker) code.
@@ -80,55 +92,51 @@ Replace the contents of your `index.js` file with the code below to view the eff
8092
```js
8193
export default {
8294
async fetch(request, env) {
83-
const { pathname } = new URL(request.url);
84-
// if (pathname === "/api/beverages") {
85-
// // If you did not use `DB` as your binding name, change it here
86-
// const { results } = await env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?",).bind("Bs Beverages").all();
87-
// return Response.json(results);
88-
// }
95+
const { pathname } = new URL(request.url);
96+
// if (pathname === "/api/beverages") {
97+
// // If you did not use `DB` as your binding name, change it here
98+
// const { results } = await env.DB.prepare("SELECT * FROM Customers WHERE CompanyName = ?",).bind("Bs Beverages").all();
99+
// return Response.json(results);
100+
// }
89101
const companyName1 = `Bs Beverages`;
90102
const companyName2 = `Around the Horn`;
91103
const stmt = env.DB.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`);
92104
const stmtMulti = env.DB.prepare(`SELECT * FROM Customers; SELECT * FROM Customers WHERE CompanyName = ?`);
93105
const session = env.DB.withSession("first-primary")
94106
const sessionStmt = session.prepare(`SELECT * FROM Customers WHERE CompanyName = ?`);
95107

96-
if (pathname === `/RUN`){
97-
const returnValue = await stmt.bind(companyName1).run();
98-
return Response.json(returnValue);
99-
100-
} else if (pathname === `/RAW`){
101-
const returnValue = await stmt.bind(companyName1).raw();
102-
return Response.json(returnValue);
103-
104-
} else if (pathname === `/FIRST`){
105-
const returnValue = await stmt.bind(companyName1).first();
106-
return Response.json(returnValue);
107-
108-
} else if (pathname === `/BATCH`) {
109-
const batchResult = await env.DB.batch([
110-
stmt.bind(companyName1),
111-
stmt.bind(companyName2)
112-
]);
113-
return Response.json(batchResult);
114-
115-
} else if (pathname === `/EXEC`){
116-
const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`);
117-
return Response.json(returnValue);
118-
119-
} else if (pathname === `/WITHSESSION`){
120-
const returnValue = await sessionStmt.bind(companyName1).run();
121-
console.log("You're now using D1 Sessions!")
122-
return Response.json(returnValue);
123-
}
124-
125-
return new Response(
126-
`Welcome to the D1 API Playground!
127-
\nChange the URL to test the various methods inside your index.js file.`,
128-
);
129-
},
130-
};
131-
```
108+
if (pathname === `/RUN`){
109+
const returnValue = await stmt.bind(companyName1).run();
110+
return Response.json(returnValue);
111+
} else if (pathname === `/RAW`){
112+
const returnValue = await stmt.bind(companyName1).raw();
113+
return Response.json(returnValue);
114+
} else if (pathname === `/FIRST`){
115+
const returnValue = await stmt.bind(companyName1).first();
116+
return Response.json(returnValue);
117+
} else if (pathname === `/BATCH`) {
118+
const batchResult = await env.DB.batch([
119+
stmt.bind(companyName1),
120+
stmt.bind(companyName2)
121+
]);
122+
return Response.json(batchResult);
123+
} else if (pathname === `/EXEC`){
124+
const returnValue = await env.DB.exec(`SELECT * FROM Customers WHERE CompanyName = "Bs Beverages"`);
125+
return Response.json(returnValue);
126+
} else if (pathname === `/WITHSESSION`){
127+
const returnValue = await sessionStmt.bind(companyName1).run();
128+
console.log("You're now using D1 Sessions!")
129+
return Response.json(returnValue);
130+
}
131+
return new Response(
132+
`Welcome to the D1 API Playground!
133+
\nChange the URL to test the various methods inside your index.js file.`,
134+
);
135+
},
136+
137+
};
138+
139+
````
132140
</Details>
133141

134142
### 3. Deploy the Worker
@@ -159,3 +167,4 @@ export default {
159167

160168
Change the URL to test the various D1 Worker Binding APIs.
161169

170+
````

0 commit comments

Comments
 (0)