surrealdb_sql/statements/
insert.rs1use crate::ctx::Context;
2use crate::dbs::{Iterable, Iterator, Options, Statement, Transaction};
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::{Data, Output, Timeout, Value};
6use derive::Store;
7use revision::revisioned;
8use serde::{Deserialize, Serialize};
9use std::fmt;
10
11#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
12#[revisioned(revision = 1)]
13pub struct InsertStatement {
14 pub into: Value,
15 pub data: Data,
16 pub ignore: bool,
17 pub update: Option<Data>,
18 pub output: Option<Output>,
19 pub timeout: Option<Timeout>,
20 pub parallel: bool,
21}
22
23impl InsertStatement {
24 pub(crate) fn writeable(&self) -> bool {
26 true
27 }
28 pub(crate) async fn compute(
30 &self,
31 ctx: &Context<'_>,
32 opt: &Options,
33 txn: &Transaction,
34 doc: Option<&CursorDoc<'_>>,
35 ) -> Result<Value, Error> {
36 opt.valid_for_db()?;
38 let mut i = Iterator::new();
40 let opt = &opt.new_with_futures(false).with_projections(false);
42 match self.into.compute(ctx, opt, txn, doc).await? {
44 Value::Table(into) => match &self.data {
45 Data::ValuesExpression(v) => {
47 for v in v {
48 let mut o = Value::base();
50 for (k, v) in v.iter() {
52 let v = v.compute(ctx, opt, txn, None).await?;
53 o.set(ctx, opt, txn, k, v).await?;
54 }
55 let id = o.rid().generate(&into, true)?;
57 i.ingest(Iterable::Mergeable(id, o));
59 }
60 }
61 Data::SingleExpression(v) => {
63 let v = v.compute(ctx, opt, txn, doc).await?;
64 match v {
65 Value::Array(v) => {
66 for v in v {
67 let id = v.rid().generate(&into, true)?;
69 i.ingest(Iterable::Mergeable(id, v));
71 }
72 }
73 Value::Object(_) => {
74 let id = v.rid().generate(&into, true)?;
76 i.ingest(Iterable::Mergeable(id, v));
78 }
79 v => {
80 return Err(Error::InsertStatement {
81 value: v.to_string(),
82 })
83 }
84 }
85 }
86 _ => unreachable!(),
87 },
88 v => {
89 return Err(Error::InsertStatement {
90 value: v.to_string(),
91 })
92 }
93 }
94 let stm = Statement::from(self);
96 i.output(ctx, opt, txn, &stm).await
98 }
99}
100
101impl fmt::Display for InsertStatement {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103 f.write_str("INSERT")?;
104 if self.ignore {
105 f.write_str(" IGNORE")?
106 }
107 write!(f, " INTO {} {}", self.into, self.data)?;
108 if let Some(ref v) = self.update {
109 write!(f, " {v}")?
110 }
111 if let Some(ref v) = self.output {
112 write!(f, " {v}")?
113 }
114 if let Some(ref v) = self.timeout {
115 write!(f, " {v}")?
116 }
117 if self.parallel {
118 f.write_str(" PARALLEL")?
119 }
120 Ok(())
121 }
122}