I have 2 files, the contents of the files pasted at the end:
1). poll.rs
2). dbmanager.rs
function 'all_poll_question' from the poll.rs calls a generic function 'find_all_by_query' in the file dbmanager.rs
poll.rs
use std::collections::HashMap;
use super::super::DBMANAGER;
use super::super::db::models::PollQuestion;
use super::super::db::schema::poll_question;
use diesel::QueryDsl;
pub struct PollQuestionService{}
impl PollQuestionService{
pub fn new()->Self{PollQuestionService{}}
pub fn create_poll_question(&self){
}
pub fn update_poll_question(&self, poll_question: PollQuestion)->bool{
DBMANAGER.insert_or_update::<PollQuestion, poll_question::table>(poll_question)
}
pub fn all_poll_question(&self, pagination:HashMap<&str, &str>, id_param:Option<String>, topic_param:Option<String>,
question_param:Option<String>, status_param:Option<String>, created_by_param:Option<String>,
date_from_param:Option<String>, date_to_param:Option<String>){
use super::super::db::schema::poll_question::dsl::*;
use crate::diesel::associations::HasTable;
use crate::diesel::ExpressionMethods;
use crate::diesel::TextExpressionMethods;
let mut query = poll_question::table().into_boxed::<diesel::sqlite::Sqlite>();
if let Some(id_val) = id_param {
query = query.filter(id.eq(id_val.parse::<i32>().unwrap()));
}
if let Some(topic_val) = topic_param {
query = query.filter(topic.like(topic_val));
}
if let Some(question_val) = question_param {
query = query.filter(question.like(question_val));
}
if let Some(created_by_val) = created_by_param{
query = query.filter(created_by.like(created_by_val));
}
if let Some(status_val) = status_param{
query = query.filter(status.eq(status_val));
}
if let Some(from_dt_val) = date_from_param{
query = query.filter(created_on.ge(from_dt_val));
}
if let Some(to_dt_val) = date_to_param{
query = query.filter(created_on.le(to_dt_val));
}
let rows:i64 = if let Some(rows) = pagination.get("rows"){
let r:i64 = rows.parse::<i32>().unwrap().into();
query = query.limit(r);
r
}else{
1
};
if let Some(page) = pagination.get("page"){
let page:i64 = page.parse::<i32>().unwrap().into();
let offset = (page-1) * rows;
query = query.offset(offset);
}
let sord = if let Some(sort) = pagination.get("sord"){
sort
}else{
"asc"
};
if let Some(order) = pagination.get("sidx"){
match order{
&"id" =>{
if sord == "desc"{
query = query.order(id.desc());
}else{
query = query.order(id.asc());
}
}
&"topic" =>{
if sord == "desc"{
query = query.order(topic.desc());
}else{
query = query.order(topic.asc());
}
}
&"question" =>{
if sord == "desc"{
query = query.order(question.desc());
}else{
query = query.order(question.asc());
}
}
&"status" =>{
if sord == "desc"{
query = query.order(status.desc());
}else{
query = query.order(status.asc());
}
}
&"created_by" =>{
if sord == "desc"{
query = query.order(created_by.desc());
}else{
query = query.order(created_by.asc());
}
}
&"created_on" =>{
if sord == "desc"{
query = query.order(created_on.desc());
}else{
query = query.order(created_on.asc());
}
}
_ =>{
if sord == "desc"{
query = query.order(id.desc());
}else{
query = query.order(id.asc());
}
}
};
}
let results = DBMANAGER.find_all_by_query::<PollQuestion,poll_question::table>(query);
}
}
dbmanager.rs
use diesel::{prelude::*,sql_query,};
use diesel::sql_types::Integer;
use diesel::RunQueryDsl;
use diesel::r2d2::{self, ConnectionManager};
use diesel::SqliteConnection;
use diesel::associations::HasTable;
use diesel::query_dsl::{QueryDsl, LoadQuery};
use std::collections::HashMap;
use diesel::result::Error;
use diesel::table;
use super::models::*;
use serde_json::Value;
use super::super::util::utility::PollCache;
use serde::Serialize;
use diesel::sqlite::{Sqlite, SqliteType};
use diesel::query_builder::{InsertStatement, Query, QueryFragment, QueryBuilder};
use diesel::query_dsl::methods::{ExecuteDsl, FilterDsl, BoxedDsl};
use super::super::SERVER_CONFIG;
use diesel::helper_types::IntoBoxed;
use diesel::types::HasSqlType;
use super::schema::poll_question::dsl::poll_question;
use diesel::query_builder::QueryId;
use crate::db::schema::poll_question::BoxedQuery;
//use crate::db::schema::user::BoxedQuery;
//use crate::db::schema::poll_question::BoxedQuery;
pub type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
pub struct DbManager{
pool: Pool,
}
impl DbManager {
pub fn new() -> DbManager {
let dbpath = SERVER_CONFIG.get_ConfigValue("database.url");
let database_pool: Pool = Pool::builder().build(ConnectionManager::new(dbpath)).unwrap();
DbManager {
pool: database_pool,
}
}
pub fn all_users(&self) -> Vec<User> {
use super::schema::user::dsl::*;
let db_connection = self.pool.get().unwrap();
let users_collection = user.load::<User>(&db_connection).expect("Error loading users");
users_collection
}
pub fn count_all_users(&self) -> i64 {
use super::schema::user::dsl::*;
let db_connection = self.pool.get().unwrap();
let users_count: i64 = user.count().get_result(&db_connection).expect("Error while count on users");
users_count
}
pub fn create<C, T>(&self, model: C) -> bool
where
T: diesel::associations::HasTable,
<T::Table as diesel::QuerySource>::FromClause:
diesel::query_builder::QueryFragment<diesel::sqlite::Sqlite>,
C: diesel::Insertable<T::Table>,
C::Values: diesel::insertable::CanInsertInSingleQuery<diesel::sqlite::Sqlite>
+ diesel::query_builder::QueryFragment<diesel::sqlite::Sqlite>,
{
let db_connection = self.pool.get().unwrap();
match diesel::insert_into(T::table()).values(model).execute(&db_connection) {
Ok(count) => {
println!("entity {:?} created", count);
true
}
Err(error) => {
println!("error encountered while creating {:?} entity", error);
false
}
}
}
pub fn insert_or_update<C, T>(&self, model: C) -> bool
where
T: diesel::associations::HasTable,
<T::Table as diesel::QuerySource>::FromClause:
diesel::query_builder::QueryFragment<diesel::sqlite::Sqlite>,
C: diesel::Insertable<T::Table>,
C::Values: diesel::insertable::CanInsertInSingleQuery<diesel::sqlite::Sqlite>
+ diesel::query_builder::QueryFragment<diesel::sqlite::Sqlite>,
{
let db_connection = self.pool.get().unwrap();
match db_connection.transaction::<_, Error, _>(|| {
diesel::replace_into(T::table()).values(model).execute(&db_connection)
}) {
Ok(_) => {
println!("saved !!!");
true
}
Err(error) => {
println!("not saved: {:?} ", error);
false
}
}
}
pub fn find_all_by_query<C, T>(&self, query: T)->Vec<C>
where
T: diesel::query_dsl::methods::LoadQuery<diesel::sqlite::SqliteConnection,C>,
{
let db_connection = self.pool.get().unwrap();
let collection = query.load::<C>(&db_connection).expect("Error in getting all records");
collection
}
}
I'm unable to implement the generic function ' find_all_by_query' accepting a boxed query as the argument for any kind of table.