-
Notifications
You must be signed in to change notification settings - Fork 23
Description
I really get sore eyes when I see Box<dyn Something>
in rust code. It's not an idiomatic rust to use them, they bypass type safety and they hurt performance.
I understand that the API is oriented around trait objects so as to be able to link your compiled program against any driver at runtime. There certainly are cases where people would want to build apps that are compiled-once and which work with any database at runtime, but there are also cases where people would want to use RDBC API for accessing just one particular database. It's obvious that in the second case performance is harmed, and more importantly, type safety is lost. Also, API in the current state doesn't allow for downcasting or any other method of accessing concrete types which I found to be of use, although rarely, for some driver specific behavior when using JDBC. I think backdoors are always a nice to have feature in any API.
I would like to propose an alternative which would include best of both worlds. This means that API would use generics instead of trait objects like this:
pub trait Driver: Sync + Send {
type C: Connection
fn connect(&self, url: &str) -> Result<Self::C>;
}
pub trait Connection {
type S: Statement;
fn create(&mut self, sql: &str) -> Result<Self::S>;
fn prepare(&mut self, sql: &str) -> Result<Self::S>;
}
pub trait Statement {
type RS: ResultSet;
fn execute_query(&mut self, params: &[Value]) -> Result<RS>;
fn execute_update(&mut self, params: &[Value]) -> Result<u64>;
}
This API would support native compilation for any driver used, but the limitation is that the driver would have to be known in compile time. To handle that limitation, the trick is to make a driver-agnostic concrete implementation of the API which would wrap trait objects, it would hide the boxed API and expose it as generic. This way the user would only have to choose whether he wants his code compiled against native implementation or driver-agnostic implementation of the API.
PS: Compiling this project is broken. It complains that it cannot compile sqlparser