surrealdb-sql 1.1.0

Full type definitions for the SurrealQL query language
Documentation
use super::super::{
	comment::shouldbespace,
	error::{expected, ExplainResultExt},
	literal::{param, table},
	part::{
		data::{single, update, values},
		output, timeout,
	},
	value::value,
	IResult,
};
use crate::{statements::InsertStatement, Value};
use nom::{
	branch::alt,
	bytes::complete::tag_no_case,
	combinator::{cut, map, opt},
	sequence::{preceded, terminated},
};

pub fn insert(i: &str) -> IResult<&str, InsertStatement> {
	let (i, _) = tag_no_case("INSERT")(i)?;
	let (i, _) = shouldbespace(i)?;
	let (i, ignore) = opt(terminated(tag_no_case("IGNORE"), shouldbespace))(i)?;
	let (i, _) = tag_no_case("INTO")(i)?;
	let (i, _) = shouldbespace(i)?;
	let (i, into) = expected(
		"a parameter or a table name",
		cut(alt((
			map(terminated(table, shouldbespace), Value::Table),
			map(terminated(param, shouldbespace), Value::Param),
		))),
	)(i)
	.explain("expressions aren't allowed here.", value)?;
	let (i, data) = cut(alt((values, single)))(i)?;
	let (i, update) = opt(preceded(shouldbespace, update))(i)?;
	let (i, output) = opt(preceded(shouldbespace, output))(i)?;
	let (i, timeout) = opt(preceded(shouldbespace, timeout))(i)?;
	let (i, parallel) = opt(preceded(shouldbespace, tag_no_case("PARALLEL")))(i)?;
	Ok((
		i,
		InsertStatement {
			into,
			data,
			ignore: ignore.is_some(),
			update,
			output,
			timeout,
			parallel: parallel.is_some(),
		},
	))
}

#[cfg(test)]
mod tests {

	use super::*;

	#[test]
	fn insert_statement_basic() {
		let sql = "INSERT INTO test (field) VALUES ($value)";
		let res = insert(sql);
		let out = res.unwrap().1;
		assert_eq!("INSERT INTO test (field) VALUES ($value)", format!("{}", out))
	}

	#[test]
	fn insert_statement_ignore() {
		let sql = "INSERT IGNORE INTO test (field) VALUES ($value)";
		let res = insert(sql);
		let out = res.unwrap().1;
		assert_eq!("INSERT IGNORE INTO test (field) VALUES ($value)", format!("{}", out))
	}

	#[test]
	fn insert_statement_ignore_update() {
		let sql = "INSERT IGNORE INTO test (field) VALUES ($value) ON DUPLICATE KEY UPDATE field = $value";
		let res = insert(sql);
		let out = res.unwrap().1;
		assert_eq!("INSERT IGNORE INTO test (field) VALUES ($value) ON DUPLICATE KEY UPDATE field = $value", format!("{}", out))
	}
}