1use std::collections::HashMap;
65
66use crate::{Query, QueryBuilder, QueryBuilderTrait, TableBuilder, TablePrimaryKey, Value};
67
68#[cfg(feature = "libsql")]
69pub mod libsql;
70#[cfg(feature = "rusqlite")]
71pub mod rusqlite;
72
73pub trait GeekConnector<'a, C>
77where
78 C: GeekConnection<Connection = C> + 'a,
79 Self: Sized + TableBuilder + QueryBuilderTrait + serde::Serialize + serde::de::DeserializeOwned,
80{
81 #[allow(async_fn_in_trait, unused_variables)]
83 async fn query(connection: &'a C, query: Query) -> Result<Vec<Self>, crate::Error> {
84 C::query::<Self>(connection, query).await
85 }
86
87 #[allow(async_fn_in_trait, unused_variables)]
89 async fn query_first(connection: &'a C, query: Query) -> Result<Self, crate::Error> {
90 C::query_first::<Self>(connection, query).await
91 }
92
93 #[allow(async_fn_in_trait, unused_variables)]
95 async fn execute(connection: &'a C, query: Query) -> Result<(), crate::Error> {
96 C::execute(connection, query).await
97 }
98
99 #[allow(async_fn_in_trait, unused_variables)]
101 async fn create_table(connection: &'a C) -> Result<(), crate::Error> {
102 C::create_table::<Self>(connection).await
103 }
104
105 #[allow(async_fn_in_trait, unused_variables)]
107 async fn row_count(connection: &'a C, query: Query) -> Result<i64, crate::Error> {
108 C::row_count(connection, query).await
109 }
110
111 #[allow(async_fn_in_trait, unused_variables)]
113 async fn total(connection: &'a C) -> Result<i64, crate::Error> {
114 C::row_count(
115 connection,
116 Self::query_count().table(Self::table()).build()?,
117 )
118 .await
119 }
120
121 #[allow(async_fn_in_trait, unused_variables)]
123 async fn all(connection: &'a C) -> Result<Vec<Self>, crate::Error> {
124 C::query::<Self>(
125 connection,
126 Self::query_select().table(Self::table()).build()?,
127 )
128 .await
129 }
130
131 #[cfg(feature = "pagination")]
133 #[allow(async_fn_in_trait, unused_variables)]
134 async fn page(connection: &'a C, page: &crate::Page) -> Result<Vec<Self>, crate::Error> {
135 C::query::<Self>(
136 connection,
137 QueryBuilder::select()
138 .table(Self::table())
139 .page(page)
140 .build()?,
141 )
142 .await
143 }
144
145 #[cfg(feature = "pagination")]
148 #[allow(async_fn_in_trait, unused_variables)]
149 async fn paginate(connection: &'a C) -> Result<crate::Pagination<Self>, crate::Error> {
150 let mut page = crate::Pagination::new();
151 page.set_total(Self::total(connection).await? as u32);
152 Ok(page)
153 }
154
155 #[allow(async_fn_in_trait, unused_variables)]
157 async fn update(&mut self, connection: &'a C) -> Result<(), crate::Error> {
158 C::execute(connection, Self::query_update(self)).await
159 }
160
161 #[allow(async_fn_in_trait, unused_variables)]
163 async fn save(&mut self, connection: &'a C) -> Result<(), crate::Error>;
164
165 #[allow(async_fn_in_trait, unused_variables)]
167 async fn delete(&self, connection: &'a C) -> Result<(), crate::Error> {
168 C::execute(connection, Self::query_delete(self)).await
169 }
170
171 #[allow(async_fn_in_trait, unused_variables)]
173 async fn fetch(&mut self, connection: &'a C) -> Result<(), crate::Error>;
174
175 #[allow(async_fn_in_trait, unused_variables)]
185 async fn filter(
186 connection: &'a C,
187 fields: Vec<(&str, impl Into<Value>)>,
188 ) -> Result<Vec<Self>, crate::Error> {
189 Self::query(
190 connection,
191 Self::query_select()
192 .table(Self::table())
193 .filter(fields)
194 .build()?,
195 )
196 .await
197 }
198
199 #[cfg(feature = "pagination")]
201 #[allow(async_fn_in_trait, unused_variables)]
202 async fn filter_page(
203 connection: &'a C,
204 fields: Vec<(&str, impl Into<Value>)>,
205 page: &crate::Page,
206 ) -> Result<Vec<Self>, crate::Error> {
207 Self::query(
208 connection,
209 Self::query_select()
210 .table(Self::table())
211 .filter(fields)
212 .page(page)
213 .build()?,
214 )
215 .await
216 }
217
218 #[deprecated(
220 since = "0.8.4",
221 note = "Please use the `all` method instead of `fetch_all`"
222 )]
223 #[allow(async_fn_in_trait, unused_variables)]
224 async fn fetch_all(connection: &'a C) -> Result<Vec<Self>, crate::Error> {
225 C::query::<Self>(
226 connection,
227 QueryBuilder::select().table(Self::table()).build()?,
228 )
229 .await
230 }
231
232 #[allow(async_fn_in_trait, unused_variables)]
234 async fn fetch_or_create(&mut self, connection: &'a C) -> Result<(), crate::Error>;
235
236 #[cfg(feature = "search")]
238 #[allow(async_fn_in_trait, unused_variables)]
239 async fn search(
240 connection: &'a C,
241 search: impl Into<String>,
242 ) -> Result<Vec<Self>, crate::Error>;
243
244 #[allow(async_fn_in_trait, unused_variables)]
246 async fn first(connection: &'a C) -> Result<Self, crate::Error>
247 where
248 Self: TablePrimaryKey,
249 {
250 C::query_first::<Self>(
251 connection,
252 Self::query_select()
253 .table(Self::table())
254 .order_by(
255 &Self::primary_key(),
256 crate::builder::models::QueryOrder::Asc,
257 )
258 .limit(1)
259 .build()?,
260 )
261 .await
262 }
263
264 #[allow(async_fn_in_trait, unused_variables)]
266 async fn last(connection: &'a C) -> Result<Self, crate::Error>
267 where
268 Self: TablePrimaryKey,
269 {
270 C::query_first::<Self>(
271 connection,
272 Self::query_select()
273 .table(Self::table())
274 .order_by(
275 &Self::primary_key(),
276 crate::builder::models::QueryOrder::Desc,
277 )
278 .limit(1)
279 .build()?,
280 )
281 .await
282 }
283}
284
285pub trait GeekConnection {
288 type Connection;
290
291 #[allow(async_fn_in_trait, unused_variables)]
293 async fn create_table<T>(connection: &Self::Connection) -> Result<(), crate::Error>
294 where
295 T: TableBuilder
296 + QueryBuilderTrait
297 + Sized
298 + serde::Serialize
299 + serde::de::DeserializeOwned,
300 {
301 Err(crate::Error::NotImplemented)
302 }
303
304 #[allow(async_fn_in_trait, unused_variables)]
306 async fn row_count(connection: &Self::Connection, query: Query) -> Result<i64, crate::Error> {
307 Err(crate::Error::NotImplemented)
308 }
309
310 #[allow(async_fn_in_trait, unused_variables)]
312 async fn execute(connection: &Self::Connection, query: Query) -> Result<(), crate::Error> {
313 Err(crate::Error::NotImplemented)
314 }
315
316 #[allow(async_fn_in_trait, unused_variables)]
318 async fn batch(connection: &Self::Connection, query: Query) -> Result<(), crate::Error> {
319 Err(crate::Error::NotImplemented)
320 }
321
322 #[allow(async_fn_in_trait, unused_variables)]
324 async fn query<T>(connection: &Self::Connection, query: Query) -> Result<Vec<T>, crate::Error>
325 where
326 T: serde::de::DeserializeOwned,
327 {
328 Err(crate::Error::NotImplemented)
329 }
330
331 #[allow(async_fn_in_trait, unused_variables)]
336 async fn query_first<T>(connection: &Self::Connection, query: Query) -> Result<T, crate::Error>
337 where
338 T: serde::de::DeserializeOwned,
339 {
340 Err(crate::Error::NotImplemented)
341 }
342
343 #[allow(async_fn_in_trait, unused_variables)]
345 async fn query_raw(
346 connection: &Self::Connection,
347 query: Query,
348 ) -> Result<Vec<HashMap<String, Value>>, crate::Error> {
349 Err(crate::Error::NotImplemented)
350 }
351
352 #[cfg(feature = "migrations")]
354 #[allow(async_fn_in_trait, unused_variables)]
355 async fn table_names(connection: &Self::Connection) -> Result<Vec<String>, crate::Error> {
356 let results: Vec<TableNames> = Self::query(
358 connection,
359 Query {
360 query: "SELECT name FROM sqlite_master WHERE type='table'".to_string(),
361 query_type: crate::builder::models::QueryType::Select,
362 ..Default::default()
363 },
364 )
365 .await?;
366
367 Ok(results
369 .iter()
370 .filter_map(|table| {
371 if table.name != "sqlite_sequence" {
372 Some(table.name.clone())
373 } else {
374 None
375 }
376 })
377 .collect())
378 }
379
380 #[cfg(feature = "migrations")]
382 #[allow(async_fn_in_trait, unused_variables)]
383 async fn pragma_info(
384 connection: &Self::Connection,
385 table: &str,
386 ) -> Result<Vec<TableInfo>, crate::Error> {
387 Self::query(
388 connection,
389 Query {
390 query: format!("PRAGMA table_info({})", table),
391 query_type: crate::builder::models::QueryType::Select,
392 ..Default::default()
393 },
394 )
395 .await
396 }
397}
398
399#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
401pub struct TableInfo {
402 pub cid: i32,
404 pub name: String,
406 #[serde(rename = "type")]
408 pub coltype: String,
409 pub notnull: i32,
411 pub dflt_value: Option<String>,
413 pub pk: i32,
415}
416
417#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
419struct TableNames {
420 pub name: String,
422}