Skip to content

Commit

Permalink
Prototype of doing correct typechecking for select_by queries
Browse files Browse the repository at this point in the history
  • Loading branch information
weiznich committed Sep 23, 2020
1 parent c108c1f commit 92c31a9
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 23 deletions.
5 changes: 3 additions & 2 deletions diesel/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,12 @@ pub trait Connection: SimpleConnection + Sized + Send {
fn execute(&self, query: &str) -> QueryResult<usize>;

#[doc(hidden)]
fn load<T, U>(&self, source: T) -> QueryResult<Vec<U>>
fn load<T, U, ST>(&self, source: T) -> QueryResult<Vec<U>>
where
T: AsQuery,
T::Query: QueryFragment<Self::Backend> + QueryId,
U: FromSqlRow<T::SqlType, Self::Backend>,
T::SqlType: crate::query_dsl::load_dsl::CompatibleType<U, Self::Backend, SqlType = ST>,
U: FromSqlRow<ST, Self::Backend>,
Self::Backend: QueryMetadata<T::SqlType>;

#[doc(hidden)]
Expand Down
26 changes: 13 additions & 13 deletions diesel/src/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use std::error::Error;
use std::result;

use crate::backend::{self, Backend};
use crate::expression::select_by::SelectBy;
use crate::expression::{helper_types::SqlTypeOf, Expression, Selectable};
//use crate::expression::select_by::SelectBy;
//use crate::expression::{helper_types::SqlTypeOf, Expression, Selectable};
use crate::row::{NamedRow, Row};
use crate::sql_types::{SingleValue, SqlType, Untyped};

Expand Down Expand Up @@ -400,17 +400,17 @@ where
}
}

impl<Q, DB, E> FromSqlRow<SelectBy<Q>, DB> for Q
where
E: Expression,
DB: Backend,
Q: Selectable<Expression = E>,
Q: FromSqlRow<SqlTypeOf<E>, DB>,
{
fn build_from_row<'a>(row: &impl Row<'a, DB>) -> Result<Self> {
<Self as FromSqlRow<SqlTypeOf<E>, DB>>::build_from_row(row)
}
}
// impl<Q, DB, E> FromSqlRow<SelectBy<Q>, DB> for Q
// where
// E: Expression,
// DB: Backend,
// Q: Selectable<Expression = E>,
// Q: FromSqlRow<SqlTypeOf<E>, DB>,
// {
// fn build_from_row<'a>(row: &impl Row<'a, DB>) -> Result<Self> {
// <Self as FromSqlRow<SqlTypeOf<E>, DB>>::build_from_row(row)
// }
// }

impl<T, ST, DB> FromStaticSqlRow<ST, DB> for T
where
Expand Down
7 changes: 5 additions & 2 deletions diesel/src/expression/select_by.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::backend::Backend;
use crate::expression::{
AppearsOnTable, Expression, QueryMetadata, Selectable, SelectableExpression, ValidGrouping,
AppearsOnTable, Expression, QueryMetadata, Selectable, SelectableExpression,
TypedExpressionType, ValidGrouping,
};
use crate::query_builder::*;
use crate::result::QueryResult;
Expand Down Expand Up @@ -36,9 +37,11 @@ where
T: Selectable<Expression = E>,
E: QueryId + Expression,
{
type SqlType = E::SqlType;
type SqlType = SelectBy<T>;
}

impl<T> TypedExpressionType for SelectBy<T> {}

impl<T, GB, E> ValidGrouping<GB> for SelectBy<T>
where
T: Selectable<Expression = E>,
Expand Down
2 changes: 1 addition & 1 deletion diesel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
// For the `specialization` feature.
#![cfg_attr(feature = "unstable", allow(incomplete_features))]
// Built-in Lints
#![deny(warnings)]
//#![deny(warnings)]
#![warn(
missing_debug_implementations,
missing_copy_implementations,
Expand Down
57 changes: 56 additions & 1 deletion diesel/src/query_dsl/load_dsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,74 @@ pub trait LoadQuery<Conn, U>: RunQueryDsl<Conn> {
fn internal_load(self, conn: &Conn) -> QueryResult<Vec<U>>;
}

use crate::expression::TypedExpressionType;
use crate::sql_types::{SqlType, Untyped};

pub trait CompatibleType<U, DB> {
type SqlType;
}

impl<ST, U, DB> CompatibleType<U, DB> for ST
where
DB: Backend,
ST: SqlType,
U: FromSqlRow<ST, DB>,
{
type SqlType = ST;
}

impl<U, DB> CompatibleType<U, DB> for Untyped
where
U: FromSqlRow<Untyped, DB>,
DB: Backend,
{
type SqlType = Untyped;
}

impl<U, DB, E, ST> CompatibleType<U, DB> for SelectBy<U>
where
DB: Backend,
ST: SqlType + TypedExpressionType,
U: Selectable<Expression = E>,
E: Expression<SqlType = ST>,
U: FromSqlRow<ST, DB>,
{
type SqlType = ST;
}

impl<Conn, T, U> LoadQuery<Conn, U> for T
where
Conn: Connection,
T: AsQuery + RunQueryDsl<Conn>,
T::Query: QueryFragment<Conn::Backend> + QueryId,
U: FromSqlRow<T::SqlType, Conn::Backend>,
T::SqlType: CompatibleType<U, Conn::Backend>,
Conn::Backend: QueryMetadata<T::SqlType>,
U: FromSqlRow<<T::SqlType as CompatibleType<U, Conn::Backend>>::SqlType, Conn::Backend>,
{
fn internal_load(self, conn: &Conn) -> QueryResult<Vec<U>> {
conn.load(self)
}
}

use crate::expression::select_by::SelectBy;
use crate::Expression;
use crate::Selectable;

// impl<Conn, T, U, E, ST> LoadQuery<Conn, U> for T
// where
// Conn: Connection,
// T: AsQuery<SqlType = SelectBy<U>> + RunQueryDsl<Conn>,
// T::Query: QueryFragment<Conn::Backend> + QueryId,
// U: Selectable<Expression = E>,
// E: Expression<SqlType = ST>,
// U: FromSqlRow<ST, Conn::Backend>,
// Conn::Backend: QueryMetadata<ST>,
// {
// fn internal_load(self, conn: &Conn) -> QueryResult<Vec<U>> {
// conn.load(self)
// }
// }

/// The `execute` method
///
/// This trait should not be relied on directly by most apps. Its behavior is
Expand Down
7 changes: 4 additions & 3 deletions diesel/src/sqlite/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,17 @@ impl Connection for SqliteConnection {
}

#[doc(hidden)]
fn load<T, U>(&self, source: T) -> QueryResult<Vec<U>>
fn load<T, U, ST>(&self, source: T) -> QueryResult<Vec<U>>
where
T: AsQuery,
T::Query: QueryFragment<Self::Backend> + QueryId,
U: FromSqlRow<T::SqlType, Self::Backend>,
T::SqlType: crate::query_dsl::load_dsl::CompatibleType<U, Sqlite, SqlType = ST>,
U: FromSqlRow<ST, Sqlite>,
Self::Backend: QueryMetadata<T::SqlType>,
{
let mut statement = self.prepare_query(&source.as_query())?;
let statement_use = StatementUse::new(&mut statement);
let iter = StatementIterator::new(statement_use);
let iter = StatementIterator::<_, U>::new(statement_use);
iter.collect()
}

Expand Down
3 changes: 2 additions & 1 deletion diesel_migrations/migrations_internals/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ where
>: ExecuteDsl<T>,
__diesel_schema_migrations: methods::SelectDsl<version>,
Select<__diesel_schema_migrations, version>: LoadQuery<T, String>,
Limit<Select<__diesel_schema_migrations, max<version>>>: QueryFragment<T::Backend>,
Limit<Select<__diesel_schema_migrations, max<version>>>:
QueryFragment<T::Backend> + LoadQuery<T, Option<String>>,
T::Backend: QueryMetadata<Nullable<VarChar>>,
{
fn previously_run_migration_versions(&self) -> QueryResult<HashSet<String>> {
Expand Down

0 comments on commit 92c31a9

Please sign in to comment.