首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用柴油机r2d2实现数据库模块中的默认特征API?

用柴油机r2d2实现数据库模块中的默认特征API?
EN

Stack Overflow用户
提问于 2021-12-21 14:05:15
回答 1查看 119关注 0票数 0

我对生锈/柴油很陌生。尝试用默认特性API (避免重复代码工作),通过机箱柴油和r2d2来实现数据库模块。

这是model.rs

代码语言:javascript
复制
use chrono::NaiveDate;
use diesel;
use diesel::Queryable;

#[derive(Queryable)]
pub struct NetWorthModel {
    pub fund_code: String,
    pub date: NaiveDate,
    pub create_time: i64,
    pub update_time: i64,
    pub payload: String,
}

这是database.rs

代码语言:javascript
复制
use diesel::connection::Connection;
use diesel::mysql::MysqlConnection;
use diesel::prelude::*;
use diesel::r2d2::{ConnectionManager, Pool};
use diesel::sqlite::SqliteConnection;
use once_cell::sync::Lazy;
use r2d2::PooledConnection;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use chrono::prelude::NaiveDate;

static MYSQL_POOL_MAP: Lazy<Mutex<HashMap<String, Pool<ConnectionManager<MysqlConnection>>>>> =
    Lazy::new(|| Mutex::new(HashMap::new()));

static SQLITE_POOL_MAP: Lazy<Mutex<HashMap<String, Pool<ConnectionManager<SqliteConnection>>>>> =
    Lazy::new(|| Mutex::new(HashMap::new()));

pub struct MysqlDatabase {
    pool: Pool<ConnectionManager<MysqlConnection>>,
}

pub struct SqliteDatabase {
    pool: Pool<ConnectionManager<SqliteConnection>>,
}

pub trait Database<Conn> {
  fn connection(&self) -> Conn; // MysqlDatabase and SqliteDatabase will ipmlement this api

  fn paged_query(&self, fund_code: &str, start_date: NaiveDate, end_date: NaiveDate) -> Vec<NetWorthModel> {
    use super::schema::tb_net_worth::dsl;
    dsl::tb_net_worth
         .filter(dsl::fund_code.eq(fund_code))
         .filter(dsl::date.ge(start_date))
         .filter(dsl::date.lt(end_date))
         .load::<NetWorthModel>(&self.connection()) // here we use the abstract API
         .unwrap()
  }
}

impl Database<PooledConnection<ConnectionManager<MysqlConnection>>> for MysqlDatabase {
    fn connection(&self) -> PooledConnection<ConnectionManager<MysqlConnection>> {
        self.pool.get().unwrap()
    }
}

impl Database<PooledConnection<ConnectionManager<SqliteConnection>>> for SqliteDatabase {
    fn connection(&self) -> PooledConnection<ConnectionManager<SqliteConnection>> {
        self.pool.get().unwrap()
    }
}

Database特性将实现所有的API,这些API应该同时适用于mysql和sqlite。但是,下面是编译错误:

代码语言:javascript
复制
error[E0277]: the trait bound `Conn: Connection` is not satisfied
   --> src/quant/common/persistence/database.rs:221:45
    |
221 |                 .load::<NetWorthQueryModel>(&self.connection())
    |                  ----                       ^^^^^^^^^^^^^^^^^^ the trait `Connection` is not implemented for `Conn`
    |                  |
    |                  required by a bound introduced by this call
    |
    = note: required because of the requirements on the impl of `LoadQuery<Conn, NetWorthQueryModel>` for `diesel::query_builder::SelectStatement<table, diesel::query_builder::select_clause::DefaultSelectClause, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<And<And<diesel::expression::operators::Eq<columns::fund_code, diesel::expression::bound::Bound<diesel::sql_types::Text, &str>>, GtEq<columns::date, diesel::expression::bound::Bound<diesel::sql_types::Date, NaiveDate>>>, Lt<columns::date, diesel::expression::bound::Bound<diesel::sql_types::Date, NaiveDate>>>>, diesel::query_builder::order_clause::OrderClause<Asc<columns::date>>, diesel::query_builder::limit_clause::LimitClause<diesel::expression::bound::Bound<diesel::sql_types::BigInt, i64>>, diesel::query_builder::offset_clause::OffsetClause<diesel::expression::bound::Bound<diesel::sql_types::BigInt, i64>>>`
help: consider restricting type parameter `Conn`
    |
147 | pub trait Database<Conn: diesel::Connection> {
    |                        ++++++++++++++++++++

按照编译器的建议,我添加了pub trait Database<Conn: diesel::Connection>,编译器给出了另一个错误:

代码语言:javascript
复制
error[E0277]: the trait bound `NaiveDate: FromSql<diesel::sql_types::Date, <Conn as Connection>::Backend>` is not satisfied
   --> src/quant/common/persistence/database.rs:221:18
    |
221 |                 .load::<NetWorthQueryModel>(&self.connection())
    |                  ^^^^ the trait `FromSql<diesel::sql_types::Date, <Conn as Connection>::Backend>` is not implemented for `NaiveDate`
    |
    = note: required because of the requirements on the impl of `diesel::Queryable<diesel::sql_types::Date, <Conn as Connection>::Backend>` for `NaiveDate`
    = note: 2 redundant requirements hidden
    = note: required because of the requirements on the impl of `diesel::Queryable<(diesel::sql_types::Text, diesel::sql_types::Date, diesel::sql_types::BigInt, diesel::sql_types::BigInt, diesel::sql_types::Text), <Conn as Connection>::Backend>` for `NetWorthQueryModel`
    = note: required because of the requirements on the impl of `LoadQuery<Conn, NetWorthQueryModel>` for `diesel::query_builder::SelectStatement<table, diesel::query_builder::select_clause::DefaultSelectClause, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<And<And<diesel::expression::operators::Eq<columns::fund_code, diesel::expression::bound::Bound<diesel::sql_types::Text, &str>>, GtEq<columns::date, diesel::expression::bound::Bound<diesel::sql_types::Date, NaiveDate>>>, Lt<columns::date, diesel::expression::bound::Bound<diesel::sql_types::Date, NaiveDate>>>>, diesel::query_builder::order_clause::OrderClause<Asc<columns::date>>, diesel::query_builder::limit_clause::LimitClause<diesel::expression::bound::Bound<diesel::sql_types::BigInt, i64>>, diesel::query_builder::offset_clause::OffsetClause<diesel::expression::bound::Bound<diesel::sql_types::BigInt, i64>>>`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
    |
147 | pub trait Database<Conn: Connection> where NaiveDate: FromSql<diesel::sql_types::Date, <Conn as Connection>::Backend> {
    |                                      ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

看起来锈菌无法检测到Backend of Connection。但我不知道该怎么解决这个问题。

请帮我解决这个问题。

EN

回答 1

Stack Overflow用户

发布于 2021-12-21 15:53:10

解决这一问题的正确方法是遵循编译器的错误消息,并引入必要的特征界限。没有他们这是行不通的。作为一般建议:尝试使用required because of给出的最后一个边界,因为这样可以避免许多其他界限。

一般来说:如果你是柴油新手,而且生锈了,那么尝试编写试图抽象柴油的通用代码可能是不可取的。这需要预先了解生锈特性系统+柴油API。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70436732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档