Avoid extra copy from `Vec<u8>` in actix form

Hello! I'm using this crate to handle file uploads GitHub - JSH32/actix-multipart-extract: Better multipart form support for Actix Web that I later insert in a postgres database as a byte array.

My function looks like this

pub async fn backup_upload(
    form: Multipart<DbUpload>,
    request: HttpRequest,
    pool: web::Data<PgPool>,
) -> impl Responder {
    ...
    match sqlx::query(
        r#"
        INSERT INTO core_saveddata(
        data, data_hash)
        VALUES ($1, $2)
        "#,
    )
    .bind(&form.db_file.bytes)
    .bind(form.original_hash.to_string())
    .execute(pool.get_ref())
    .await

and I'm trying it in a memory constrained environment. My issue is that the bytes is a Vec<u8> and when using sqlx &form.db_file.bytes duplicates the memory since it creates a copy as a &[u8]. Is there a way to avoid having a copy and just use the original vector? The copy effect is that the memory usage gets doubled and my container dies.

If I use directly the form.db_file.bytes I get

error[E0507]: cannot move out of dereference of `Multipart<DbUpload>`
  --> src/routes/backups.rs:94:11
   |
94 |     .bind(form.db_file.bytes)
   |           ^^^^^^^^^^^^^^^^^^ move occurs because value has type `Vec<u8>`, which does not implement the `Copy` trait

If you don't need the value of the bytes field anymore, you can replace it with an empty vector using std::mem::take().

Thank you very much! I didn't know about this function. That seems to have fixed the issue but found that sqlx does an extra allocation of memory that is quite bi. Thank you again, I learned something new today.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.