shindo_coding_utils 0.3.8

A utils crates which will be used in various micro-services
Documentation
use async_trait::async_trait;
use sea_orm::{sea_query::OnConflict, *};
use std::sync::Arc;

use crate::{
    schemas::following_investor::{ActiveModel, Column, Entity, Model},
    types::UserPost,
};

#[async_trait]
pub trait FollowingInvestorRepository: Send + Sync {
    async fn insert_following_investor_posts(
        &self,
        user_posts: &Vec<UserPost>,
    ) -> Result<InsertResult<ActiveModel>, DbErr>;

    async fn find_all_investor_posts(&self) -> Result<Vec<Model>, DbErr>;
}

pub struct SeaOrmFollowingInvestorRepository {
    db_conn: Arc<DatabaseConnection>,
}

impl SeaOrmFollowingInvestorRepository {
    pub fn new(db_conn: Arc<DatabaseConnection>) -> Self {
        Self { db_conn }
    }
}

#[async_trait]
impl FollowingInvestorRepository for SeaOrmFollowingInvestorRepository {
    async fn insert_following_investor_posts(
        &self,
        investor_posts: &Vec<UserPost>,
    ) -> Result<InsertResult<ActiveModel>, DbErr> {
        let active_models = investor_posts.iter().map(move |post| {
            let tagged_symbols_str = post
                .tagged_symbols
                .iter()
                .map(|ts| ts.symbol.clone())
                .collect::<Vec<_>>()
                .join("-");

            let active_model = ActiveModel {
                user_id: Set(post.user.id.clone()),
                post_id: Set(post.post_id),
                content: Set(post.content.clone()),
                post_type: Set(post.post_type.clone()),
                tagged_symbols: Set(tagged_symbols_str),
                post_timestamp: Set(post.date),
                ..Default::default()
            };

            return active_model;
        });

        let unique_columns = [Column::UserId, Column::PostId, Column::PostTimestamp];
        let on_conflict = OnConflict::columns(unique_columns)
            .update_columns(unique_columns)
            .to_owned();

        let res = Entity::insert_many(active_models)
            .on_conflict(on_conflict.clone())
            .exec(&*self.db_conn)
            .await?;
        Ok(res)
    }

    async fn find_all_investor_posts(&self) -> Result<Vec<Model>, DbErr> {
        Entity::find().all(&*self.db_conn).await
    }
}