use {
super::{columns_to_positions, validate},
crate::{
data::Schema, types::ComplexTableName, ExecuteError, Glue, Payload, Result, Row, Value,
},
sqlparser::ast::{Ident, ObjectName, Query},
};
impl Glue {
pub async fn ast_insert(
&mut self,
table_name: &ObjectName,
columns: &[Ident],
source: &Query,
expect_data: bool,
) -> Result<Payload> {
let ComplexTableName {
name: table_name,
database,
..
} = &table_name.try_into()?;
let columns = columns
.iter()
.map(|column| column.value.as_str())
.collect::<Vec<_>>();
let (labels, rows) = self.ast_query(source.clone()).await?;
self.true_insert(
database,
table_name,
&columns,
rows,
Some(labels),
expect_data,
)
.await
}
pub async fn true_insert(
&mut self,
database: &Option<String>,
table: &str,
columns: &[&str],
mut rows: Vec<Vec<Value>>,
labels: Option<Vec<String>>,
expect_data: bool,
) -> Result<Payload> {
let Schema {
column_defs,
indexes,
..
} = self
.get_database(database)?
.fetch_schema(table)
.await?
.ok_or(ExecuteError::TableNotExists)?;
let column_positions = columns_to_positions(&column_defs, columns)?;
validate(&column_defs, &column_positions, &mut rows)?;
let mut rows: Vec<Row> = rows.into_iter().map(Row).collect();
#[cfg(feature = "auto-increment")]
self.auto_increment(database, table, &column_defs, &mut rows)
.await?;
self.validate_unique(database, table, &column_defs, &rows, None)
.await?;
let num_rows = rows.len();
let result = if expect_data {
Payload::Select {
labels: labels.unwrap_or_default(),
rows: rows.clone(),
}
} else {
Payload::Insert(num_rows)
};
self.insert_data(database, table, rows).await?;
if !indexes.is_empty() {
let database = &mut **self.get_mut_database(database)?;
for index in indexes.iter() {
index.reset(database, table, &column_defs).await?; }
}
Ok(result)
}
pub async fn insert_data(
&mut self,
database: &Option<String>,
table_name: &str,
rows: Vec<Row>,
) -> Result<()> {
let database = &mut **self.get_mut_database(database)?;
database.insert_data(table_name, rows).await
}
}