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

Generic BoxedQuery for functions? #546

Closed
durango opened this Issue Dec 17, 2016 · 1 comment

Comments

Projects
None yet
2 participants
@durango
Contributor

durango commented Dec 17, 2016

Basically, trying to refactor code a bit for my app and have the following:

use params::Map;
use diesel::prelude::*;
use diesel::pg::Pg;

struct ListData<Table> {
    _marker: PhantomData<Table>
}

impl<ST> ListData<ST> where
    ST: Table
{
    pub fn set_page<'a, T>(params: &Map, max_items: i64, source: &mut T) -> &'a BoxedSelectStatement<'a, <ST as Table>::AllColumns, ST, Pg> where
        T: QuerySource + AsQuery,
        T::Query: InternalBoxedDsl<'a, Pg>
    {
        // match params.find(&["page"]) {
        //     Some(&ParamsValue::String(ref page)) => {
        //         let mut current_page = page.parse::<i64>().unwrap_or(0);
        //         if current_page < 1 {
        //             current_page = 0
        //         }
        //
        //         source = source.offset(current_page * max_items)
        //     },
        //     _ => (),
        // }

        source = source.limit(max_items)
    }
}

let map = itry!(req.get_ref::<Params>());
let mut source = users::table.into_boxed::<Pg>();
source = ListData::<users::table>::set_page(map, 30, &mut source);

And then the error:

error: no method named `limit` found for type `&mut T` in the current scope
  --> src/users/routes.rs:74:25
   |
74 |         source = source.limit(max_items)
   |                         ^^^^^
   |
   = note: the method `limit` exists but the following trait bounds were not satisfied: `&mut T : diesel::QuerySource`, `&mut T : diesel::query_builder::AsQuery`, `_ : diesel::LimitDsl`, `&mut T : diesel::query_builder::Query`, `&&mut T : diesel::QuerySource`, `&&mut T : diesel::query_builder::AsQuery`, `_ : diesel::LimitDsl`, `&&mut T : diesel::query_builder::Query`, `&mut &mut T : diesel::QuerySource`, `&mut &mut T : diesel::query_builder::AsQuery`, `_ : diesel::LimitDsl`, `&mut &mut T : diesel::query_builder::Query`, `<T as diesel::query_builder::AsQuery>::Query : diesel::LimitDsl`, `&T : diesel::QuerySource`, `&T : diesel::query_builder::AsQuery`, `_ : diesel::LimitDsl`, `&T : diesel::query_builder::Query`, `&mut T : diesel::QuerySource`, `&mut T : diesel::query_builder::AsQuery`, `_ : diesel::LimitDsl`, `&mut T : diesel::query_builder::Query`
   = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `limit`, perhaps you need to implement it:
   = help: candidate #1: `diesel::LimitDsl`

error[E0275]: overflow evaluating the requirement `diesel::query_builder::BoxedSelectStatement<'_, (diesel::types::Integer, diesel::types::Text, diesel::types::Text, diesel::types::Text, diesel::types::Nullable<diesel::types::Text>, diesel::types::Bool, diesel::types::Nullable<diesel::types::Timestamptz>, diesel::types::Nullable<diesel::types::Integer>, diesel::types::Text), schema::users::table, diesel::pg::Pg>: diesel::QuerySource`
   --> src/users/routes.rs:140:14
    |
140 |     source = ListData::<users::table>::set_page(map, 30, &mut source);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: consider adding a `#![recursion_limit="128"]` attribute to your crate
    = note: required because of the requirements on the impl of `diesel::boxed_dsl::InternalBoxedDsl<'_, diesel::pg::Pg>` for `diesel::query_builder::BoxedSelectStatement<'_, (diesel::types::Integer, diesel::types::Text, diesel::types::Text, diesel::types::Text, diesel::types::Nullable<diesel::types::Text>, diesel::types::Bool, diesel::types::Nullable<diesel::types::Timestamptz>, diesel::types::Nullable<diesel::types::Integer>, diesel::types::Text), schema::users::table, diesel::pg::Pg>`
@sgrif

This comment has been minimized.

Member

sgrif commented Jan 3, 2017

This code will look fairly ugly if it's generic, but this is roughly what you'd want:

impl<T> ListData<T> where
    T: Table,
{
    pub fn set_page<'a, DB>(params: &Map, max_items: i64, source: BoxedSelectStatement<'a, T::SqlType, T, DB>) -> BoxedSelectStatement<'a, T::SqlType, T, DB> where
        DB: Backend + HasSqlType<T::SqlType>,
    {
        // your code
    }
}

You may need to disambiguate T::SqlType by writing <T as AsQuery>::SqlType.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment