6 releases (breaking)

0.6.0 Dec 14, 2023
0.5.0 Oct 2, 2023
0.4.0 Oct 2, 2023
0.3.0 Oct 2, 2023
0.1.0 Oct 1, 2023

#5 in #tiberius

Download history 4/week @ 2024-08-30 1/week @ 2024-09-13 10/week @ 2024-09-20 11/week @ 2024-09-27 1/week @ 2024-10-04 10/week @ 2024-10-18 21/week @ 2024-10-25 48/week @ 2024-11-01 60/week @ 2024-11-08 15/week @ 2024-11-15 7/week @ 2024-11-22 6/week @ 2024-11-29 24/week @ 2024-12-06 55/week @ 2024-12-13

93 downloads per month
Used in eventful-sql-server

MIT license

5KB

tiberius-mappers

Row mappers for the Tiberius SQL Server driver.

See the published crate and the documentation for more information.

  • Allows you to map tiberius rows to structs
  • Defines a TryFromRow trait for tiberius::Row
  • Supports deriving the TryFromRow traits for structs via the tiberius-mappers-derive crate
  • Requires the columns in the SQL query to be in the same order as the struct fields
  • Handles null values where these map to Option fields in the struct
  • Currently maps by name in FromRowBorrowed and by index in FromRowOwned

The existing tiberius-derive crate currently offers more options for mapping, but does not seem to be maintained and doesn't work with newer versions of Tiberius. I have been maintaining a fork of this crate to support newer versions of Tiberius in internal builds, but I wanted to start from scratch with a simpler implementation. Note that this implementation is based on the original tiberius-derive crate, so credit to the original authors for the idea and some of the code.

Usage

This is a work in progress. Currently, the TryFromRow mapper is implemented.


use tiberius_mappers::TryFromRow;

#[derive(TryFromRow)] // Derive the FromRow trait on our struct
pub struct Customer {
    pub id: i32,
    pub first_name: String,
    pub last_name: String,
    pub description: Option<String>,
}

pub async fn print_customers(rows: Vec<tiberius::Row>) -> Result<(), Box<dyn std::error::Error>> {
    
    // Now we can call the try_from_row method on each row to get a Customer struct
    let customers: Vec<Customer> = rows
            .into_iter()
            .map(Customer::try_from_row).collect::<Result<Vec<Customer>, _>>()?;

    for customer in customers {
        println!("Customer: {} - {:?} - {:?}", customer.id, customer.first_name, customer.last_name);
    }

    Ok(())
}


TODO

  • Add more tests (proc macros are not as straightforward to test!)
  • Add an option to validate the row names in the returned query result set against the struct field for safety
  • Improve error messages
  • Possibly support renaming fields (maybe, not sure if this is a good idea). This would need to interact with the row name validation option mentioned above.

Dependencies

~6.5MB
~184K SLoC