How in the Rust bindings do I know an LWT failed?

Getting my feet wet with a small app with scylladb. I have a unique key I don’t want duplicated on insert so I have an LWT like below. I’m curious how I can know the LWT failed so I can return back a true/false so I can alert the client appropriately that the username is taken in case a race condition bypasses the basic client check.

pub async fn create_user(session: Session, user: User) -> anyhow::Result<()> {

    session.query(r#"
        INSERT INTO labeling.users
        (username,password_hash,first_name,last_name,created_at) 
        VALUES
        (?,?,?,?,?)
        IF NOT EXISTS;
    "#,user).await?;

    return Ok(());
}

pub async fn create_user(session: &Session, user: &User) -> anyhow::Result<bool> {

   let row = session.query(r#"
        INSERT INTO labeling.users
        (username,password_hash,email,first_name,last_name,created_at) 
        VALUES
        (?,?,?,?,?,?)
        IF NOT EXISTS;
    "#,(
        user.username.clone(),
        user.password_hash.clone(),
        user.email.clone(),
        user.first_name.clone(),
        user.last_name.clone(),
        user.created_at
    )).await?.first_row()?;

    if let Some(Some(applied)) = row.columns.get(0) {
        return Ok(applied.as_boolean().unwrap());
    }

    return Ok(false);
}

So the first row of any insert with ‘IF NOT EXISTS’ is always a boolean with the name ‘applied’. However, what makes this complicated is if the row DOES exist it will also return the existing row. This means the output format changes based on if it succeeds or not …

The code above was the best way I could find to handle that.

You must be playing with Cassandra, in Scylla the statement metadata is stable: How does Scylla LWT Differ from Apache Cassandra ? | ScyllaDB Docs

3 Likes