Skip to content

Commit

Permalink
added route for cryptocurrencies
Browse files Browse the repository at this point in the history
  • Loading branch information
0xMimir committed Oct 2, 2023
1 parent 4e719fa commit b40049e
Show file tree
Hide file tree
Showing 25 changed files with 177 additions and 53 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ env_logger = "0.10.0"
tokio-cron-scheduler = "0.9.4"
async-trait = "0.1.73"
chrono = { version = "0.4.31", features = ["serde"] }
actix = "0.13.1"
actix-web = "4.4.0"

error.path = "libs/error"
sdks.path = "libs/sdks"
Expand Down
2 changes: 2 additions & 0 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ config.workspace = true
env_logger.workspace = true
tokio-cron-scheduler.workspace = true
async-trait.workspace = true
actix.workspace = true
actix-web.workspace = true

[[bin]]
path = "src/main.rs"
Expand Down
10 changes: 9 additions & 1 deletion api/src/api/cryptocurrencies/contract.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
use error::Result;
use store::objects::CryptoCurrencyView;

#[async_trait]
pub trait DbRepository{
pub trait DbRepositoryContract{
async fn get_cryptocurrencies(&self) -> Result<Vec<CryptoCurrencyView>>;
}

#[async_trait]
pub trait CryptocurrenciesContract{
async fn get_cryptocurrencies(&self) -> Result<Vec<CryptoCurrencyView>>;
}
14 changes: 14 additions & 0 deletions api/src/api/cryptocurrencies/domain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use super::contract::{CryptocurrenciesContract, DbRepositoryContract};
use error::Result;
use store::objects::CryptoCurrencyView;

pub struct Cryptocurrencies<A: DbRepositoryContract> {
pub(super) repository: A,
}

#[async_trait]
impl<A: DbRepositoryContract + Send + Sync> CryptocurrenciesContract for Cryptocurrencies<A> {
async fn get_cryptocurrencies(&self) -> Result<Vec<CryptoCurrencyView>> {
self.repository.get_cryptocurrencies().await
}
}
11 changes: 11 additions & 0 deletions api/src/api/cryptocurrencies/handlers/get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use actix_web::{web::Data, HttpResponse};
use error::Result;

use crate::api::cryptocurrencies::contract::CryptocurrenciesContract;

pub async fn get_cryptocurrencies<S: CryptocurrenciesContract>(
service: Data<S>,
) -> Result<HttpResponse> {
let value = service.get_cryptocurrencies().await?;
Ok(HttpResponse::Ok().json(value))
}
2 changes: 2 additions & 0 deletions api/src/api/cryptocurrencies/handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod get;
pub use get::get_cryptocurrencies;
24 changes: 22 additions & 2 deletions api/src/api/cryptocurrencies/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
use std::sync::Arc;

use actix_web::web::{self, resource, Data, ServiceConfig};
use sea_orm::DatabaseConnection;

use self::{domain::Cryptocurrencies, handlers::*, repository::PgRepository};

mod contract;
mod repository;
mod domain;
mod handlers;
mod handlers;
mod repository;

pub fn setup(conn: Arc<DatabaseConnection>, config: &mut ServiceConfig) {
let state = Cryptocurrencies {
repository: PgRepository::new(conn),
};

config.app_data(Data::new(state));

config.service(
resource("/api/{version}/crypto")
.route(web::get().to(get_cryptocurrencies::<Cryptocurrencies<PgRepository>>)),
);
}
71 changes: 38 additions & 33 deletions api/src/api/cryptocurrencies/repository.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
use sea_orm::{DatabaseConnection, EntityTrait, QueryFilter, ColumnTrait, QuerySelect};
use error::{Error, Result};
use sea_orm::{
sea_query::Expr, ColumnTrait, DatabaseConnection, EntityTrait, JoinType, QueryFilter,
QuerySelect, RelationTrait, SelectColumns,
};
use std::sync::Arc;
use store::{cryptocurrencies, github_projects, github_repositories, issues};
use store::{
cryptocurrencies, github_projects, github_repositories, issues, objects::CryptoCurrencyView,
};

use super::contract::DbRepositoryContract;

pub struct PgRepository {
conn: Arc<DatabaseConnection>,
Expand All @@ -12,41 +20,38 @@ impl PgRepository {
}
}

impl PgRepository {
pub fn fetch(&self) {
let query = github_projects::Entity::find()
#[async_trait]
impl DbRepositoryContract for PgRepository {
async fn get_cryptocurrencies(&self) -> Result<Vec<CryptoCurrencyView>> {
github_projects::Entity::find()
.inner_join(cryptocurrencies::Entity)
.left_join(github_repositories::Entity)
.join_rev(
JoinType::LeftJoin,
issues::Relation::GithubRepositories.def(),
)
.filter(github_repositories::Column::RepositoryName.is_not_null())
.group_by(cryptocurrencies::Column::Id)
.group_by(cryptocurrencies::Column::Name)
.group_by(cryptocurrencies::Column::CoingeckoId)
.group_by(cryptocurrencies::Column::Github )
.group_by(github_projects::Column::Name) ;
.group_by(cryptocurrencies::Column::Github)
.group_by(github_projects::Column::Name)
.select_only()
.columns([
cryptocurrencies::Column::Id,
cryptocurrencies::Column::Name,
cryptocurrencies::Column::CoingeckoId,
])
.select_column_as(cryptocurrencies::Column::Github, "github_id")
.column_as(github_projects::Column::Name, "github")
.expr(Expr::cust_with_expr(
"array_agg(distinct $1) as repositories",
github_repositories::Column::RepositoryName.into_expr(),
))
.column_as(issues::Column::Id.count(), "issues")
.into_model::<CryptoCurrencyView>()
.all(self.conn.as_ref())
.await
.map_err(Error::from)
}
}
/*
select
c.id,
c."name",
c.coingecko_id,
c.github,
gp."name",
array_agg(gr.repository_name),
count(i)
from
cryptocurrencies c
inner join github_projects gp on
gp.id = c.github
left join github_repositories gr on
gr.project = gp.id
left join issues i on
i.repository = gr.id
where gr.repository_name notnull
group by
c.id,
c."name",
c.coingecko_id,
c.github,
gp."name"
*/
}
26 changes: 25 additions & 1 deletion api/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
mod cryptocurrencies;
use std::sync::Arc;

use actix_web::{dev::Server, web::ServiceConfig, App, HttpServer};
use sea_orm::DatabaseConnection;

mod cryptocurrencies;

pub fn create_api(conn: Arc<DatabaseConnection>) -> Server {
let workers = match config::get_default("IS_DEV", "false").as_str() == "true" {
true => 1,
false => config::get_default("ACTIX_WORKERS", "8")
.parse()
.unwrap_or(8),
};

HttpServer::new(move || App::new().configure(|config| configure_routes(conn.clone(), config)))
.workers(workers)
.bind(("localhost", 1111))
.expect("Unable to start sever")
.run()
}

fn configure_routes(conn: Arc<DatabaseConnection>, config: &mut ServiceConfig) {
cryptocurrencies::setup(conn, config);
}
5 changes: 4 additions & 1 deletion api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ extern crate log;
extern crate async_trait;

pub mod jobs;
mod api;
mod api;

pub use jobs::setup as setup_jobs;
pub use api::create_api;
13 changes: 4 additions & 9 deletions api/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::{sync::Arc, time::Duration};

use api::jobs;
use api::{create_api, setup_jobs};
use config::dotenv_init;
use sea_orm::Database;
use tokio::time::interval;
use std::sync::Arc;

#[tokio::main]
async fn main() {
Expand All @@ -16,10 +14,7 @@ async fn main() {
let pool = Database::connect(db_url).await.unwrap();
let sea_pool = Arc::new(pool);

let _handles = jobs::setup(sea_pool);
let _handles = setup_jobs(sea_pool.clone());

let mut period = interval(Duration::from_millis(100));
loop {
period.tick().await;
}
create_api(sea_pool).await.expect("Error starting server");
}
4 changes: 4 additions & 0 deletions libs/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ pub fn get(key: &str) -> Result<String> {
pub fn dotenv_init() {
dotenv::dotenv().expect("Error running reading dotenv");
}

pub fn get_default(key: &str, default: &str) -> String{
get(key).unwrap_or(default.to_owned())
}
1 change: 1 addition & 0 deletions libs/error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web.workspace = true
reqwest.workspace = true
sea-orm.workspace = true
serde_json.workspace = true
Expand Down
10 changes: 10 additions & 0 deletions libs/error/src/actix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use actix_web::{HttpResponse, ResponseError};

use crate::Error;

impl ResponseError for Error {
fn error_response(&self) -> HttpResponse {
println!("{}", self);
HttpResponse::Ok().finish()
}
}
2 changes: 2 additions & 0 deletions libs/error/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use thiserror::Error;

mod actix;

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Error, Debug)]
Expand Down
1 change: 1 addition & 0 deletions libs/store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ edition = "2021"

[dependencies]
sea-orm.workspace =true
serde.workspace = true
10 changes: 4 additions & 6 deletions libs/store/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3
#[macro_use] extern crate serde;

pub mod prelude;
mod migrations;
pub mod objects;

pub mod cryptocurrencies;
pub mod github_projects;
pub mod github_repositories;
pub mod issues;
pub use migrations::*;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions libs/store/src/migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3

pub mod prelude;

pub mod cryptocurrencies;
pub mod github_projects;
pub mod github_repositories;
pub mod issues;
File renamed without changes.
12 changes: 12 additions & 0 deletions libs/store/src/objects/cryptocurrencies.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use sea_orm::{prelude::Uuid, FromQueryResult};

#[derive(FromQueryResult, Serialize)]
pub struct CryptoCurrencyView {
pub id: Uuid,
pub name: String,
pub coingecko_id: String,
pub github_id: Uuid,
pub github: String,
pub repositories: Vec<String>,
pub issues: i64,
}
2 changes: 2 additions & 0 deletions libs/store/src/objects/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod cryptocurrencies;
pub use cryptocurrencies::CryptoCurrencyView;

0 comments on commit b40049e

Please sign in to comment.