I create a connection type, i.e.
let mut conn = Connection::open("sqlite.db").unwrap();
And then I pass that type to my save_all function along with a vector, like this:
pub fn save_all(conn: &mut Connection,
vehicles: Vec<Vehicle>) -> Result<(), Error> {
let tx = conn.transaction()?;
for v in vehicles {
let sql: &str =
"INSERT INTO local_edits (vehicle_id, make, model, color)
VALUES (:vehicle_id, :make, :model, :color)";
let mut statement = tx.prepare(sql)?;
statement.execute(named_params! {
":vehicle_id": v.vehicle_id,
":make": v.make,
":model": v.model,
":color": v.color})?;
};
tx.commit()?;
return Ok(());
}
This code seems to work okay. Is this code actually correct?
If I don't make my conn
type &mut Connection in the save_all
function, the code doesn't compile for me. It tells me:
Cannot borrow immutable local variable `conn` as mutable
I'm not quite sure how to understand this.
And is the right pattern to pass conn's "reference" to my save_all
function?
I don’t want to transfer ownership to this function. I think I just want to let the function borrow the connection.
Cannot borrow immutable local variable
conn
as mutable
The mut
in &mut Connection
is necessary because you are calling transaction
on conn
which requires a mutable reference. See also the documentation for this API callI which expects a &mut self
.
Borrowing vs. transfer of ownership
Borrowing seems like the right way to do this in case you want to re-use the connection later again. If you would transfer ownership of the connection you'd have to return it again as part of the result in order to re-use it later (because of how affine types in rust work). This would be less-ergonomic to work with than just borrowing the connection.