1use std::future;
2
3use futures_core::future::BoxFuture;
4use futures_core::stream::BoxStream;
5use futures_util::{stream, FutureExt, StreamExt, TryFutureExt};
6use sqlx_core::describe::Describe;
7use sqlx_core::error::Error;
8use sqlx_core::executor::{Execute, Executor};
9use sqlx_core::sql_str::SqlStr;
10use sqlx_core::Either;
11use worker::send::SendFuture;
12use worker::worker_sys::types::D1PreparedStatement as D1PreparedStatementSys;
13
14use crate::error::unsupported;
15use crate::{js, D1Arguments, D1Connection, D1QueryResult, D1Row, D1Statement, D1TypeInfo, D1};
16
17impl<'c> Executor<'c> for &'c D1Connection {
22 type Database = D1;
23
24 fn execute<'e, 'q: 'e, E>(self, query: E) -> BoxFuture<'e, Result<D1QueryResult, Error>>
27 where
28 'c: 'e,
29 E: 'q + Execute<'q, D1>,
30 {
31 SendFuture::new(async move {
32 let statement = prepare(self, query)?;
33 js::run(&statement).await
34 })
35 .boxed()
36 }
37
38 fn execute_many<'e, 'q: 'e, E>(self, query: E) -> BoxStream<'e, Result<D1QueryResult, Error>>
39 where
40 'c: 'e,
41 E: 'q + Execute<'q, D1>,
42 {
43 stream::once(self.execute(query)).boxed()
44 }
45
46 fn fetch_many<'e, 'q: 'e, E>(
50 self,
51 query: E,
52 ) -> BoxStream<'e, Result<Either<D1QueryResult, D1Row>, Error>>
53 where
54 'c: 'e,
55 E: 'q + Execute<'q, D1>,
56 {
57 SendFuture::new(async move {
58 let statement = prepare(self, query)?;
59 js::fetch(&statement, None).await
60 })
61 .map_ok(|rows| stream::iter(rows.into_iter().map(|row| Ok(Either::Right(row)))))
62 .try_flatten_stream()
63 .boxed()
64 }
65
66 fn fetch_optional<'e, 'q: 'e, E>(self, query: E) -> BoxFuture<'e, Result<Option<D1Row>, Error>>
67 where
68 'c: 'e,
69 E: 'q + Execute<'q, D1>,
70 {
71 SendFuture::new(async move {
72 let statement = prepare(self, query)?;
73 Ok(js::fetch(&statement, Some(1)).await?.into_iter().next())
74 })
75 .boxed()
76 }
77
78 fn prepare_with<'e>(
79 self,
80 sql: SqlStr,
81 _parameters: &'e [D1TypeInfo],
82 ) -> BoxFuture<'e, Result<D1Statement, Error>>
83 where
84 'c: 'e,
85 {
86 future::ready(Ok(D1Statement { sql })).boxed()
87 }
88
89 fn describe<'e>(self, _sql: SqlStr) -> BoxFuture<'e, Result<Describe<D1>, Error>>
93 where
94 'c: 'e,
95 {
96 future::ready(Err(unsupported("statements cannot be described"))).boxed()
97 }
98}
99
100fn prepare<'q, E>(conn: &D1Connection, mut query: E) -> Result<D1PreparedStatementSys, Error>
102where
103 E: Execute<'q, D1>,
104{
105 let arguments = query.take_arguments().map_err(Error::Encode)?;
106 let arguments = arguments.as_ref().map_or(&[][..], D1Arguments::values);
107
108 js::prepare(&conn.db, query.sql().as_str(), arguments)
109}
110
111impl<'c> Executor<'c> for &'c mut D1Connection {
115 type Database = D1;
116
117 fn execute<'e, 'q: 'e, E>(self, query: E) -> BoxFuture<'e, Result<D1QueryResult, Error>>
118 where
119 'c: 'e,
120 E: 'q + Execute<'q, D1>,
121 {
122 (&*self).execute(query)
123 }
124
125 fn execute_many<'e, 'q: 'e, E>(self, query: E) -> BoxStream<'e, Result<D1QueryResult, Error>>
126 where
127 'c: 'e,
128 E: 'q + Execute<'q, D1>,
129 {
130 (&*self).execute_many(query)
131 }
132
133 fn fetch_many<'e, 'q: 'e, E>(
134 self,
135 query: E,
136 ) -> BoxStream<'e, Result<Either<D1QueryResult, D1Row>, Error>>
137 where
138 'c: 'e,
139 E: 'q + Execute<'q, D1>,
140 {
141 (&*self).fetch_many(query)
142 }
143
144 fn fetch_optional<'e, 'q: 'e, E>(self, query: E) -> BoxFuture<'e, Result<Option<D1Row>, Error>>
145 where
146 'c: 'e,
147 E: 'q + Execute<'q, D1>,
148 {
149 (&*self).fetch_optional(query)
150 }
151
152 fn prepare_with<'e>(
153 self,
154 sql: SqlStr,
155 parameters: &'e [D1TypeInfo],
156 ) -> BoxFuture<'e, Result<D1Statement, Error>>
157 where
158 'c: 'e,
159 {
160 (&*self).prepare_with(sql, parameters)
161 }
162
163 fn describe<'e>(self, sql: SqlStr) -> BoxFuture<'e, Result<Describe<D1>, Error>>
164 where
165 'c: 'e,
166 {
167 (&*self).describe(sql)
168 }
169}