Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design async version of traits #53

Open
andygrove opened this issue Jan 14, 2020 · 4 comments
Open

Design async version of traits #53

andygrove opened this issue Jan 14, 2020 · 4 comments
Labels
help wanted Extra attention is needed

Comments

@andygrove
Copy link
Contributor

andygrove commented Jan 14, 2020

The initial PoC of RDBC was pretty naive and copied from ODBC/JDBC and is not idiomatic Rust code. This issue has been created to discuss how to create an idiomatic Rust set of traits using async for the project.

Specific issues with the current traits:

  • Not async
  • Data access does not use generics and instead has one accessor method per datatype e.g. get_i32()
  • There are ownership issues when trying to create more than one prepared statement per connection
  • There is no support for batch or columnar, but that can potentially be addressed later
@andygrove
Copy link
Contributor Author

For reference, the current traits are:

/// Represents database driver that can be shared between threads, and can therefore implement
/// a connection pool
pub trait Driver: Sync + Send {
    /// Create a connection to the database. Note that connections are intended to be used
    /// in a single thread since most database connections are not thread-safe
    fn connect(&self, url: &str) -> Result<Box<dyn Connection>>;
}

/// Represents a connection to a database
pub trait Connection {
    /// Create a statement for execution
    fn create(&mut self, sql: &str) -> Result<Box<dyn Statement + '_>>;

    /// Create a prepared statement for execution
    fn prepare(&mut self, sql: &str) -> Result<Box<dyn Statement + '_>>;
}

/// Represents an executable statement
pub trait Statement {
    /// Execute a query that is expected to return a result set, such as a `SELECT` statement
    fn execute_query(&mut self, params: &[Value]) -> Result<Box<dyn ResultSet + '_>>;

    /// Execute a query that is expected to update some rows.
    fn execute_update(&mut self, params: &[Value]) -> Result<u64>;
}

/// Result set from executing a query against a statement
pub trait ResultSet {
    /// get meta data about this result set
    fn meta_data(&self) -> Result<Box<dyn ResultSetMetaData>>;

    /// Move the cursor to the next available row if one exists and return true if it does
    fn next(&mut self) -> bool;

    fn get_i8(&self, i: u64) -> Result<Option<i8>>;
    fn get_i16(&self, i: u64) -> Result<Option<i16>>;
    fn get_i32(&self, i: u64) -> Result<Option<i32>>;
    fn get_i64(&self, i: u64) -> Result<Option<i64>>;
    fn get_f32(&self, i: u64) -> Result<Option<f32>>;
    fn get_f64(&self, i: u64) -> Result<Option<f64>>;
    fn get_string(&self, i: u64) -> Result<Option<String>>;
    fn get_bytes(&self, i: u64) -> Result<Option<Vec<u8>>>;
}

/// Meta data for result set
pub trait ResultSetMetaData {
    fn num_columns(&self) -> u64;
    fn column_name(&self, i: u64) -> String;
    fn column_type(&self, i: u64) -> DataType;
}

@95th
Copy link
Contributor

95th commented Jan 19, 2020

The Row trait has:

    fn get_string(&self, i: u64) -> Result<Option<String>>;
    fn get_bytes(&self, i: u64) -> Result<Option<Vec<u8>>>;

Shouldn't these be

    fn get_string(&self, i: u64) -> Result<Option<&str>>;
    fn get_bytes(&self, i: u64) -> Result<Option<&[u8]>>;

The user can always get its owned version if needed.

@andygrove andygrove added the help wanted Extra attention is needed label Dec 18, 2020
@sd2k
Copy link

sd2k commented Dec 18, 2020

I wrote an experimental version of an feature gated async API here: https://github.com/sd2k/rdbc-sync-async-apis. Perhaps it would serve as a starting point for something more polished!

@sd2k
Copy link

sd2k commented Dec 18, 2020

Also the sqlx::any module may provide useful insight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants