pub struct Insert<T> { /* private fields */ }Expand description
An INSERT statement for adding rows to a table.
See the SQLite docs for details.
#[derive(Clone, PartialEq, Eq, Hash, Debug, Table, Param, ResultRecord)]
struct Food {
#[nanosql(unique)]
name: String,
sugar: u16,
energy: u32,
}
let inserted_foods = [
Food { name: "beef".into(), sugar: 0, energy: 250 },
Food { name: "fish".into(), sugar: 0, energy: 200 },
Food { name: "chocolate".into(), sugar: 61, energy: 545 },
];
let mut conn = Connection::connect_in_memory()?;
conn.create_table::<Food>()?;
let returned_foods = conn.insert_or_ignore_batch(inserted_foods.clone())?;
assert!(returned_foods.iter().flatten().eq(&inserted_foods));
// convenience query for retrieving the properties of the "fish" record
define_query! {
GetFish<'lt>: () => Single<Food> {
r#"
SELECT name AS name, sugar AS sugar, energy AS energy
FROM food
WHERE name = 'fish'
"#
}
}
// Try to insert a duplicate using various conflict resolution algorithms,
// applicable when PRIMARY KEY or UNIQUE constraints are violated.
// The default is ABORT: duplicates cause an error, the DB is not modified.
let result = conn.compile_invoke(
Insert::<Food>::new(),
Food { name: "fish".into(), sugar: 13, energy: 37 },
);
assert!(matches!(
result,
Err(Error::Sqlite(SqliteError::SqliteFailure(
FfiError {
code: ErrorCode::ConstraintViolation,
..
},
_
)))
));
assert_eq!(
conn.compile_invoke(GetFish, ())?,
Single(Food { name: "fish".into(), sugar: 0, energy: 200 }),
);
// IGNORE means no error, but the database is still not modified.
let entity = conn.compile_invoke(
Insert::<Food>::or_ignore(),
Food { name: "fish".into(), sugar: 14, energy: 38 },
)?;
assert_eq!(entity, None);
assert_eq!(
conn.compile_invoke(GetFish, ())?,
Single(Food { name: "fish".into(), sugar: 0, energy: 200 }),
);
// REPLACE means update the other fields of the conflicting row.
let entity = conn.compile_invoke(
Insert::<Food>::or_replace(),
Food { name: "fish".into(), sugar: 15, energy: 39 },
)?;
assert_eq!(
entity,
Some(Food { name: "fish".into(), sugar: 15, energy: 39 }),
);
assert_eq!(
conn.compile_invoke(GetFish, ())?,
Single(Food { name: "fish".into(), sugar: 15, energy: 39 }),
);
// INSERT OR IGNORE also works via a convenience extension method on `Connection`
let entity = conn.insert_or_ignore_one(Food {
name: "fish".into(),
sugar: 16,
energy: 49,
})?;
assert_eq!(entity, None);
assert_eq!(
conn.compile_invoke(GetFish, ())?,
Single(Food { name: "fish".into(), sugar: 15, energy: 39 }),
);
let entity = conn.insert_or_ignore_one(Food {
name: "plum".into(),
sugar: 43,
energy: 129,
})?;
assert_eq!(
entity,
Some(Food { name: "plum".into(), sugar: 43, energy: 129 })
);
// replacing also works using a convenience method on connections
let replaced = conn.insert_or_replace_one(Food {
name: "fish".into(),
sugar: 17,
energy: 64,
})?;
assert_eq!(
replaced,
Food { name: "fish".into(), sugar: 17, energy: 64 },
);
assert_eq!(
conn.compile_invoke(GetFish, ())?,
Single(replaced)
);Implementations§
Source§impl<T> Insert<T>
impl<T> Insert<T>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Creates an INSERT statement with the default conflict resolution behavior,
which is ABORT.
Sourcepub const fn with_behavior(behavior: ConflictResolution) -> Self
pub const fn with_behavior(behavior: ConflictResolution) -> Self
Creates an INSERT statement with the specified conflict resolution behavior.
Sourcepub const fn or_replace() -> Self
pub const fn or_replace() -> Self
Creates an INSERT OR REPLACE statement.
Trait Implementations§
Source§impl<T> Query for Insert<T>where
T: Table + ResultRecord,
impl<T> Query for Insert<T>where
T: Table + ResultRecord,
Source§type Output = Option<T>
type Output = Option<T>
The optional is Some(_) if the row was inserted or updated, and None
if it was ignored.
Source§fn format_sql(&self, formatter: &mut Formatter<'_>) -> Result
fn format_sql(&self, formatter: &mut Formatter<'_>) -> Result
TODO(H2CO3): respect optional/defaulted columns
Source§type Input<'p> = <T as Table>::InsertInput<'p>
type Input<'p> = <T as Table>::InsertInput<'p>
The parameter type of the query. This must be either of the following: Read more
Source§fn display_sql(&self) -> SqlDisplay<&Self>
fn display_sql(&self) -> SqlDisplay<&Self>
Returns a formatter object that displays the SQL text for this query.
impl<T> Copy for Insert<T>
Auto Trait Implementations§
impl<T> Freeze for Insert<T>
impl<T> RefUnwindSafe for Insert<T>
impl<T> Send for Insert<T>
impl<T> Sync for Insert<T>
impl<T> Unpin for Insert<T>
impl<T> UnwindSafe for Insert<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more