ormlite_core/
insert.rs

1use crate::Result;
2use futures::future::BoxFuture;
3pub use sqlmo::query::OnConflict;
4use sqlmo::{Dialect, Insert, ToSql};
5
6/// Represents an insert query.
7/// We had to turn this into a model because we need to pass in the on_conflict configuration.
8pub struct Insertion<'a, Acquire, Model, DB: sqlx::Database> {
9    pub acquire: Acquire,
10    pub model: Model,
11    pub closure: Box<dyn 'static + Send + FnOnce(Acquire, Model, String) -> BoxFuture<'a, Result<Model>>>,
12    pub insert: Insert,
13    pub _db: std::marker::PhantomData<DB>,
14}
15
16impl<'a, Acquire, Model, DB: sqlx::Database> Insertion<'a, Acquire, Model, DB> {
17    pub fn on_conflict(mut self, c: OnConflict) -> Self {
18        self.insert.on_conflict = c;
19        self
20    }
21}
22
23impl<'a, Acquire, Model: crate::model::Model<DB>, DB: sqlx::Database> std::future::IntoFuture
24    for Insertion<'a, Acquire, Model, DB>
25{
26    type Output = Result<Model>;
27    type IntoFuture = BoxFuture<'a, Self::Output>;
28
29    fn into_future(self) -> Self::IntoFuture {
30        // hack to get around the fact that postgres drops the return
31        // value in ON CONFLICT DO NOTHING case
32        // let q = if matches!(self.insert.on_conflict, OnConflict::Ignore) {
33        //     let insert_as_select = Select {
34        //         ctes: vec![
35        //             Cte::new("inserted", self.insert)
36        //         ],
37        //         columns: vec![SelectColumn::raw("*")],
38        //         from: Some("inserted".into()),
39        //         ..Select::default()
40        //     };
41        //     let pkey = Model::primary_key().unwrap();
42        //     let plc_idx = Model::primary_key_placeholder_idx().unwrap();
43        //     let select_existing = Select {
44        //         from: Some(Model::table_name().into()),
45        //         columns: Model::table_columns().iter().map(|&c| c.into()).collect(),
46        //         where_: format!("{pkey} = ${plc_idx}").into(),
47        //         ..Select::default()
48        //     };
49        //     let union = Union {
50        //         all: true,
51        //         queries: vec![
52        //             insert_as_select,
53        //             select_existing
54        //         ]
55        //     };
56        //     union.to_sql(Dialect::Postgres)
57        // } else {
58        // self.insert.to_sql(Dialect::Postgres)
59        // };
60        let q = self.insert.to_sql(Dialect::Postgres);
61        (self.closure)(self.acquire, self.model, q)
62    }
63}