Skip to content

Commit

Permalink
Added D1 example repo (cloudflare#77)
Browse files Browse the repository at this point in the history
Co-authored-by: Glen Maddern <[email protected]>
geelen and geelen authored Jun 30, 2022
1 parent ce173a3 commit 1ab3924
Showing 6 changed files with 4,042 additions and 0 deletions.
2 changes: 2 additions & 0 deletions worker-d1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
wrangler-local-state
dist
64 changes: 64 additions & 0 deletions worker-d1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Template: worker-d1

> **Note: requires D1 Beta Access**
This project is based off the Default Typescript Worker starter. To create a new project like this, run the following:

```sh
npx wrangler@d1 init -y
```

> **Note the "@d1"**—we're using a prerelease version of Wrangler under the `d1` tag. You can install this into an existing Wrangler project using `npm install wrangler@d1`
Then copy the `src` and the `data` directory from this template into your project.

Alternatively, clone this repo directly:

```sh
npm init cloudflare northwind-demo worker-d1
```

### Getting started

Next, run the following commands in the console:

```sh
# Make sure you've logged in
npx wrangler login

# Create the D1 Database
npx wrangler d1 create northwind-demo

# Add config to wrangler.toml as instructed

# Fill the DB with seed data from an SQL file:
npx wrangler d1 execute northwind-demo --file ./Northwind.Sqlite3.create.sql

# If you're creating a new project, you'll need to install some dependencies:
npm install --save-dev itty-router @cloudflare/d1

# Deploy the worker
npx wrangler publish
```

Then test out your new Worker!

### Developing locally

To develop on your worker locally, it can be super helpful to be able to copy down a copy of your production DB to work on. To do that with D1:

```sh
# Create a fresh backup on R2
npx wrangler d1 backup create northwind-demo

# Make sure you have the directory where wrangler dev looks for local D1
mkdir -p wrangler-local-state/d1

# Copy the `id` of the backup, and download the backup into that directory
npx wrangler d1 backup download northwind-demo <backup-id> --output /wrangler-local-state/d1/DB.sqlite3

# Then run wrangler dev --local with persistence
npx wrangler dev --local --experimental-enable-local-persistence
```

**Note:** the local D1 development environment is under active development and may have some incorrect behaviour. If you have issues, run `npm install wrangler@d1` to make sure you're on the latest version, or provide feedback in Discord.
3,888 changes: 3,888 additions & 0 deletions worker-d1/data/Northwind.Sqlite3.create.sql

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions worker-d1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "worker-d1",
"version": "1.0.0",
"description": "**Note: requires D1 Beta Access**",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@cloudflare/d1": "^1.4.1",
"@cloudflare/workers-types": "^3.14.0",
"itty-router": "^2.6.1",
"typescript": "^4.7.4",
"wrangler": "d1"
}
}
61 changes: 61 additions & 0 deletions worker-d1/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// NOTE: this import only required during beta. Types will be available
// on @cloudflare/workers-types after launch
import type { Database } from '@cloudflare/d1';
import { Router } from 'itty-router';
const _404 = () => new Response(null, { status: 404 });

export interface Env {
// Bindings
DB: Database;
// We can also use Env to cache things between requests
__router?: Router;
}
let router: Router;

export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
if (!env.__router) {
const router = Router();

// Figure out what tables we have in the DB
const response = await env.DB.prepare(
`SELECT name from sqlite_schema where type = ? and name NOT LIKE ?;`
)
.bind('table', 'sqlite_%')
.all();

/* TODO: Fix once Miniflare is updated (it currently returns everything as .bulk) */
const tables: Array<{ name: string }> = response.results
? response.results
: response.result[0];

// Return an index
router.get('/', async () => {
return Response.json({
tables: Object.fromEntries(
tables.map(({ name }) => [
name,
{
count: new URL(`/count/${name}`, request.url),
},
])
),
});
});

// Add a route for each table
tables.forEach(({ name }) => {
router.get('/count/' + encodeURIComponent(name), async () => {
// TODO: .first() doesn't yet work on Miniflare due to implicit .bulk
const response = await env.DB.prepare(`SELECT count(*) from [${name}];`).all();
return Response.json(response);
});
});

router.all('*', _404);
env.__router = router;
}

return env.__router.handle(request);
},
};
8 changes: 8 additions & 0 deletions worker-d1/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name = "worker-d1"
main = "src/index.ts"
compatibility_date = "2022-06-30"

[[ d1_databases ]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "northwind-demo"
database_id = "" # Replace with your ID from `wrangler d1 create`

0 comments on commit 1ab3924

Please sign in to comment.