Created query mcaro

This commit is contained in:
FlareLine 2023-02-11 00:40:57 +11:00 committed by Zeb Piasecki
parent 37e9bf42b5
commit ff994ff10d
4 changed files with 51 additions and 16 deletions

View File

@ -29,8 +29,8 @@ extern "C" {
#[wasm_bindgen(structural, method, getter, js_name=count)]
pub fn count(this: &D1ExecResult) -> Option<u32>;
#[wasm_bindgen(structural, method, getter, js_name=time)]
pub fn time(this: &D1ExecResult) -> Option<f64>;
#[wasm_bindgen(structural, method, getter, js_name=duration)]
pub fn duration(this: &D1ExecResult) -> Option<f64>;
}
#[wasm_bindgen]

38
worker/src/d1/macros.rs Normal file
View File

@ -0,0 +1,38 @@
/// Prepare a D1 query from the provided D1Database, query string, and optional query parameters.
///
/// Any parameter provided is required to implement [`serde::Serialize`] to be used.
///
/// Using [`query`] is equivalent to using db.prepare('').bind('') in Javascript.
///
/// # Example
///
/// ```
/// let query = worker::query!(
/// &d1,
/// "SELECT * FROM things WHERE num > ?1 AND num < ?2",
/// &min,
/// &max,
/// )?;
/// ```
#[macro_export]
macro_rules! query {
// rule for simple queries
($db:expr, $query:expr) => {
$crate::d1::D1Database::prepare($db, $query)
};
// rule for parameterized queries
($db:expr, $query:expr, $($args:expr),* $(,)?) => {{
|| -> $crate::Result<$crate::d1::D1PreparedStatement> {
let prepared = $crate::d1::D1Database::prepare($db, $query);
// D1 doesn't support taking in undefined values, so we translate these missing values to NULL.
let serializer = $crate::d1::serde_wasm_bindgen::Serializer::new().serialize_missing_as_null(true);
let bindings = &[$(
::serde::ser::Serialize::serialize(&$args, &serializer)
.map_err(|e| $crate::Error::Internal(e.into()))?
),*];
$crate::d1::D1PreparedStatement::bind(prepared, bindings)
}()
}};
}

View File

@ -1,7 +1,7 @@
use js_sys::Array;
use js_sys::ArrayBuffer;
use js_sys::Uint8Array;
use serde::de::Deserialize;
use serde::Deserialize;
use wasm_bindgen::{JsCast, JsValue};
use wasm_bindgen_futures::JsFuture;
use worker_sys::types::D1Database as D1DatabaseSys;
@ -13,6 +13,10 @@ use crate::env::EnvBinding;
use crate::Error;
use crate::Result;
pub use serde_wasm_bindgen;
pub mod macros;
// A D1 Database.
pub struct D1Database(D1DatabaseSys);
@ -105,7 +109,8 @@ impl From<D1DatabaseSys> for D1Database {
pub struct D1PreparedStatement(D1PreparedStatementSys);
impl D1PreparedStatement {
/// Bind one or more parameters to the statement. Returns a new statement object.
/// Bind one or more parameters to the statement.
/// Consumes the old statement and returns a new statement with the bound parameters.
///
/// D1 follows the SQLite convention for prepared statements parameter binding.
///
@ -113,17 +118,8 @@ impl D1PreparedStatement {
///
/// Supports Ordered (?NNNN) and Anonymous (?) parameters - named parameters are currently not supported.
///
pub fn bind<T>(&self, values: &[&T]) -> Result<Self>
where
T: serde::ser::Serialize + ?Sized,
{
let mut params = Vec::new();
for value in values.iter() {
let res = serde_wasm_bindgen::to_value(value)?;
params.push(res);
}
let array: Array = params.into_iter().collect::<Array>();
pub fn bind(self, values: &[JsValue]) -> Result<Self> {
let array: Array = values.into_iter().collect::<Array>();
match self.0.bind(array) {
Ok(stmt) => Ok(D1PreparedStatement(stmt)),

View File

@ -55,8 +55,9 @@ mod cache;
mod cf;
mod context;
mod cors;
// Require pub module for macro export
#[cfg(feature = "d1")]
mod d1;
pub mod d1;
mod date;
mod delay;
pub mod durable;