Skip to content

Commit 2703520

Browse files
authored
Merge branch 'main' into releases/v0.6.0
2 parents c8ec0d5 + ed9cfdd commit 2703520

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2349
-2490
lines changed

.github/workflows/pullrequest.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ jobs:
1717
components: clippy, rustfmt
1818
targets: wasm32-unknown-unknown
1919

20+
- name: Cache Rust dependencies
21+
uses: actions/cache@v4
22+
with:
23+
path: |
24+
~/.cargo/registry
25+
~/.cargo/git
26+
target
27+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
28+
restore-keys: |
29+
${{ runner.os }}-cargo-
30+
2031
- name: Check Formatting
2132
run: cargo fmt --all -- --check
2233

@@ -37,6 +48,17 @@ jobs:
3748
with:
3849
targets: wasm32-unknown-unknown
3950

51+
- name: Cache Rust dependencies
52+
uses: actions/cache@v4
53+
with:
54+
path: |
55+
~/.cargo/registry
56+
~/.cargo/git
57+
target
58+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
59+
restore-keys: |
60+
${{ runner.os }}-cargo-
61+
4062
- name: Check for errors
4163
run: cargo check
4264

Cargo.lock

Lines changed: 25 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Read the [Notes and FAQ](#notes-and-faq)
1212
use worker::*;
1313

1414
#[event(fetch)]
15-
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
15+
pub async fn main(mut req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
1616
console_log!(
1717
"{} {}, located at: {:?}, within: {}",
1818
req.method().to_string(),
@@ -221,11 +221,10 @@ For more information about how to configure these bindings, see:
221221
### Define a Durable Object in Rust
222222

223223
To define a Durable Object using the `worker` crate you need to implement the `DurableObject` trait
224-
on your own struct. Additionally, the `#[durable_object]` attribute macro must be applied to _both_
225-
your struct definition and the trait `impl` block for it.
224+
on your own struct. Additionally, the `#[durable_object]` attribute macro must be applied to the struct definition.
226225

227226
```rust
228-
use worker::*;
227+
use worker::{durable_object, State, Env, Result, Request, Response};
229228

230229
#[durable_object]
231230
pub struct Chatroom {
@@ -235,7 +234,6 @@ pub struct Chatroom {
235234
env: Env, // access `Env` across requests, use inside `fetch`
236235
}
237236

238-
#[durable_object]
239237
impl DurableObject for Chatroom {
240238
fn new(state: State, env: Env) -> Self {
241239
Self {
@@ -246,7 +244,7 @@ impl DurableObject for Chatroom {
246244
}
247245
}
248246

249-
async fn fetch(&mut self, _req: Request) -> Result<Response> {
247+
async fn fetch(&self, _req: Request) -> Result<Response> {
250248
// do some work when a worker makes a request to this DO
251249
Response::ok(&format!("{} active users.", self.users.len()))
252250
}
@@ -271,6 +269,66 @@ tag = "v1" # Should be unique for each entry
271269
new_classes = ["Chatroom"] # Array of new classes
272270
```
273271

272+
### SQLite Storage in Durable Objects
273+
274+
Durable Objects can use SQLite for persistent storage, providing a relational database interface. To enable SQLite storage, you need to use `new_sqlite_classes` in your migration and access the SQL storage through `state.storage().sql()`.
275+
276+
```rust
277+
use worker::{durable_object, State, Env, Result, Request, Response, SqlStorage};
278+
279+
#[durable_object]
280+
pub struct SqlCounter {
281+
sql: SqlStorage,
282+
}
283+
284+
impl DurableObject for SqlCounter {
285+
fn new(state: State, _env: Env) -> Self {
286+
let sql = state.storage().sql();
287+
// Create table if it does not exist
288+
sql.exec("CREATE TABLE IF NOT EXISTS counter(value INTEGER);", None)
289+
.expect("create table");
290+
Self { sql }
291+
}
292+
293+
async fn fetch(&self, _req: Request) -> Result<Response> {
294+
#[derive(serde::Deserialize)]
295+
struct Row {
296+
value: i32,
297+
}
298+
299+
// Read current value
300+
let rows: Vec<Row> = self
301+
.sql
302+
.exec("SELECT value FROM counter LIMIT 1;", None)?
303+
.to_array()?;
304+
let current = rows.get(0).map(|r| r.value).unwrap_or(0);
305+
let next = current + 1;
306+
307+
// Update counter
308+
self.sql.exec("DELETE FROM counter;", None)?;
309+
self.sql
310+
.exec("INSERT INTO counter(value) VALUES (?);", vec![next.into()])?;
311+
312+
Response::ok(format!("SQL counter is now {}", next))
313+
}
314+
}
315+
```
316+
317+
Configure your `wrangler.toml` to enable SQLite storage:
318+
319+
```toml
320+
# ...
321+
322+
[durable_objects]
323+
bindings = [
324+
{ name = "SQL_COUNTER", class_name = "SqlCounter" }
325+
]
326+
327+
[[migrations]]
328+
tag = "v1" # Should be unique for each entry
329+
new_sqlite_classes = ["SqlCounter"] # Use new_sqlite_classes for SQLite-enabled objects
330+
```
331+
274332
- For more information about migrating your Durable Object as it changes, see the docs here:
275333
https://developers.cloudflare.com/workers/learning/using-durable-objects#durable-object-migrations-in-wranglertoml
276334

0 commit comments

Comments
 (0)