use crate::SomeSharedData; use crate::{ js_sys::{Object, Reflect}, wasm_bindgen, }; use serde::Deserialize; use wasm_bindgen::JsValue; use worker::{D1PreparedArgument, D1Type, Env, Error, Request, Response, Result}; #[derive(Deserialize)] struct Person { id: u32, name: String, age: u32, } #[worker::send] pub async fn prepared_statement( _req: Request, env: Env, _data: SomeSharedData, ) -> Result { let db = env.d1("DB")?; let unbound_stmt = worker::query!(&db, "SELECT * FROM people WHERE name = ?"); let stmt = unbound_stmt.bind_refs(&D1Type::Text("Ryan Upton"))?; // All rows let results = stmt.all().await?; let people = results.results::()?; assert!(results.success()); assert_eq!(results.error(), None); assert_eq!(people.len(), 1); assert_eq!(people[0].name, "Ryan Upton"); assert_eq!(people[0].age, 21); assert_eq!(people[0].id, 6); // All columns of the first rows let person = stmt.first::(None).await?.unwrap(); assert_eq!(person.name, "Ryan Upton"); assert_eq!(person.age, 21); // The name of the first row let name = stmt.first::(Some("name")).await?.unwrap(); assert_eq!(name, "Ryan Upton"); // All of the rows as column arrays of raw JSON values. let rows = stmt.raw::().await?; assert_eq!(rows.len(), 1); let columns = &rows[0]; assert_eq!(columns[0].as_u64(), Some(6)); assert_eq!(columns[1].as_str(), Some("Ryan Upton")); assert_eq!(columns[2].as_u64(), Some(21)); let stmt_2 = unbound_stmt.bind_refs([&D1Type::Text("John Smith")])?; let person = stmt_2.first::(None).await?.unwrap(); assert_eq!(person.name, "John Smith"); assert_eq!(person.age, 92); let prepared_argument = D1PreparedArgument::new(&D1Type::Text("Dorian Fischer")); let stmt_3 = unbound_stmt.bind_refs(&prepared_argument)?; let person = stmt_3.first::(None).await?.unwrap(); assert_eq!(person.name, "Dorian Fischer"); assert_eq!(person.age, 19); Response::ok("ok") } #[worker::send] pub async fn batch(_req: Request, env: Env, _data: SomeSharedData) -> Result { let db = env.d1("DB")?; let mut results = db .batch(vec![ worker::query!(&db, "SELECT * FROM people WHERE id < 4"), worker::query!(&db, "SELECT * FROM people WHERE id > 4"), ]) .await? .into_iter(); let first_results = results.next().unwrap().results::()?; assert_eq!(first_results.len(), 3); assert_eq!(first_results[0].id, 1); assert_eq!(first_results[1].id, 2); assert_eq!(first_results[2].id, 3); let second_results = results.next().unwrap().results::()?; assert_eq!(second_results.len(), 2); assert_eq!(second_results[0].id, 5); assert_eq!(second_results[1].id, 6); Response::ok("ok") } #[worker::send] pub async fn exec(mut req: Request, env: Env, _data: SomeSharedData) -> Result { let db = env.d1("DB")?; let result = db .exec(req.text().await?.as_ref()) .await .expect("doesn't exist"); Response::ok(result.count()?.unwrap_or_default().to_string()) } #[worker::send] pub async fn dump(_req: Request, env: Env, _data: SomeSharedData) -> Result { let db = env.d1("DB")?; let bytes = db.dump().await?; Response::from_bytes(bytes) } #[worker::send] pub async fn error(_req: Request, env: Env, _data: SomeSharedData) -> Result { let db = env.d1("DB")?; let error = db .exec("THIS IS NOT VALID SQL") .await .expect_err("did not get error"); if let Error::D1(error) = error { assert_eq!( error.cause(), "Error in line 1: THIS IS NOT VALID SQL: near \"THIS\": syntax error at offset 0: SQLITE_ERROR" ); } else { panic!("expected D1 error"); } Response::ok("") } #[derive(Debug, Deserialize)] struct NullablePerson { id: u32, name: Option, age: Option, } #[worker::send] pub async fn jsvalue_null_is_null( _req: Request, _env: Env, _data: SomeSharedData, ) -> Result { assert!(wasm_bindgen::JsValue::NULL.is_null()); Response::ok("ok") } #[worker::send] pub async fn serialize_optional_none( _req: Request, _env: Env, _data: SomeSharedData, ) -> Result { let serializer = serde_wasm_bindgen::Serializer::new().serialize_missing_as_null(true); let none: Option = None; let js_none = ::serde::ser::Serialize::serialize(&none, &serializer).unwrap(); assert!(js_none.is_null()); Response::ok("ok") } #[worker::send] pub async fn serialize_optional_some( _req: Request, _env: Env, _data: SomeSharedData, ) -> Result { let serializer = serde_wasm_bindgen::Serializer::new().serialize_missing_as_null(true); let some: Option = Some("Hello".to_string()); let js_some = ::serde::ser::Serialize::serialize(&some, &serializer).unwrap(); assert!(js_some.is_string()); Response::ok("ok") } #[worker::send] pub async fn deserialize_optional_none( _req: Request, _env: Env, _data: SomeSharedData, ) -> Result { let js_value = Object::new(); Reflect::set(&js_value, &JsValue::from_str("id"), &JsValue::from_f64(1.0)).unwrap(); Reflect::set(&js_value, &JsValue::from_str("name"), &JsValue::NULL).unwrap(); Reflect::set(&js_value, &JsValue::from_str("age"), &JsValue::NULL).unwrap(); let js_value: JsValue = js_value.into(); let value: NullablePerson = serde_wasm_bindgen::from_value(js_value).unwrap(); assert_eq!(value.id, 1); assert_eq!(value.name, None); assert_eq!(value.age, None); Response::ok("ok") } #[worker::send] pub async fn insert_and_retrieve_optional_none( _req: Request, env: Env, _data: SomeSharedData, ) -> Result { let db = env.d1("DB")?; let query = worker::query!( &db, "INSERT INTO nullable_people (id, name, age) VALUES (?1, ?2, ?3)", &3, &None::, &None:: )?; query.run().await?; let stmt = worker::query!(&db, "SELECT * FROM nullable_people WHERE id = 3"); let person = stmt.first::(None).await?.unwrap(); assert_eq!(person.id, 3); assert_eq!(person.name, None); assert_eq!(person.age, None); Response::ok("ok") } #[worker::send] pub async fn insert_and_retrieve_optional_some( _req: Request, env: Env, _data: SomeSharedData, ) -> Result { let db = env.d1("DB")?; let query = worker::query!( &db, "INSERT INTO nullable_people (id, name, age) VALUES (?1, ?2, ?3)", &4, &"Dude", &12 )?; query.run().await?; let stmt = worker::query!(&db, "SELECT * FROM nullable_people WHERE id = 4"); let person = stmt.first::(None).await?.unwrap(); assert_eq!(person.id, 4); assert_eq!(person.name, Some("Dude".to_string())); assert_eq!(person.age, Some(12)); Response::ok("ok") } #[worker::send] pub async fn retrieve_optional_none( _req: Request, env: Env, _data: SomeSharedData, ) -> Result { let db = env.d1("DB")?; let stmt = worker::query!(&db, "SELECT * FROM nullable_people WHERE id = 1"); let person = stmt.first::(None).await?.unwrap(); assert_eq!(person.id, 1); assert_eq!(person.name, None); assert_eq!(person.age, None); Response::ok("ok") } #[worker::send] pub async fn retrieve_optional_some( _req: Request, env: Env, _data: SomeSharedData, ) -> Result { let db = env.d1("DB")?; let stmt = worker::query!(&db, "SELECT * FROM nullable_people WHERE id = 2"); let person = stmt.first::(None).await?.unwrap(); assert_eq!(person.id, 2); assert_eq!(person.name, Some("Wynne Ogley".to_string())); assert_eq!(person.age, Some(67)); Response::ok("ok") } #[worker::send] pub async fn retrive_first_none( _req: Request, env: Env, _data: SomeSharedData, ) -> Result { let db = env.d1("DB")?; let stmt = worker::query!(&db, "SELECT * FROM nullable_people WHERE id = 9999"); assert!(stmt.first::(None).await?.is_none()); Response::ok("ok") }