Skip to content

Instantly share code, notes, and snippets.

@indykish
Forked from anonymous/playground.rs
Created September 10, 2020 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save indykish/d16a046dc757bde7611737d8f4fb411c to your computer and use it in GitHub Desktop.
Save indykish/d16a046dc757bde7611737d8f4fb411c to your computer and use it in GitHub Desktop.
Rust code shared from the playground
mod db_schema{ // diesel generated schema
pub mod period {
pub struct table {}
pub struct tenant_id {}
}
pub mod category {
pub struct table {}
pub struct id {}
}
}
//use super::db::PgSqlConn;
struct PgSqlConn {}
use diesel;
#[derive(diesel::Queryable)]
pub struct Period {
}
#[derive(diesel::Queryable)]
pub struct Category {
}
pub trait HasTenantID {
type TenantIDColumn;
}
pub trait NoTenantID {
}
impl HasTenantID for db_schema::period::table {
type TenantIDColumn = db_schema::period::tenant_id;
}
// TODO Can this be auto implemented?
impl NoTenantID for db_schema::category::table {
}
pub struct TenantedConnection {
connection: PgSqlConn,
tenant_id: u32
}
pub trait RunQueryDsl : diesel::RunQueryDsl<TenantedConnection> {
}
impl<T> RunQueryDsl for T where T: diesel::Table + NoTenantID {
}
// error - this implementation will conflict with the implementation above
impl<T> RunQueryDsl for T where T: diesel::Table + HasTenantID {
// TODO This execute method can only be called if the query fragment includes
// a `.filter(T::TenantIDColumn.eq(Conn.tenant_id))`
// TODO Is there any way to force this in the type system?
fn execute(self, conn: &TenantedConnection) -> diesel::QueryResult<usize>
where
Self: diesel::methods::ExecuteDsl<TenantedConnection>,
{
//...
}
}
fn get_periods(conn: &TenantedConnection) -> Vec<Period> {
// This call should fail to compile - does not filter
diesel::select(db_schema::period::table)
.load::<Period>().unwrap();
// This call is okay, it filters on tenant id
diesel::select(db_schema::period::table)
.filter(db_schema::period::tenant_id.eq(conn.tenant_id))
.load::<Period>().unwrap()
}
fn get_categories(conn: &TenantedConnection) -> Vec<Category> {
// This call is fine, category has no tenant id
diesel::select(db_schema::category::table)
.load::<Category>().unwrap()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment