use super::models::{Benchmark, BenchmarkEvent, NewBenchmark, NewBenchmarkEvent};
use super::DbExecutor;
use crate::db::filters::Filters;
use actix::prelude::*;
use diesel::prelude::*;
use diesel::sql_query;
use diesel::sql_types::*;
use failure::Error;
use serde_json::Value;
#[derive(Serialize, Deserialize, Debug, QueryableByName)]
pub struct Targets {
#[sql_type = "Text"]
target: String,
}
pub enum Query {
All(Filters),
Targets(i32),
Events(i32),
}
impl Message for Query {
type Result = Result<Value, Error>;
}
impl Handler<Query> for DbExecutor {
type Result = Result<Value, Error>;
fn handle(&mut self, msg: Query, _: &mut Self::Context) -> Self::Result {
match msg {
Query::All(filters) => self.get_benchmarks(filters),
Query::Events(id) => self.get_events(id),
Query::Targets(id) => self.get_targets(id),
}
}
}
impl Message for NewBenchmark {
type Result = Result<Value, Error>;
}
impl Handler<NewBenchmark> for DbExecutor {
type Result = Result<Value, Error>;
fn handle(&mut self, msg: NewBenchmark, _: &mut Self::Context) -> Self::Result {
self.save_benchmark(msg)
}
}
impl Message for NewBenchmarkEvent {
type Result = Result<Value, Error>;
}
impl Handler<NewBenchmarkEvent> for DbExecutor {
type Result = Result<Value, Error>;
fn handle(&mut self, msg: NewBenchmarkEvent, _: &mut Self::Context) -> Self::Result {
self.save_benchmark_event(msg)
}
}
impl DbExecutor {
fn get_benchmarks(&self, _filters: Filters) -> Result<Value, Error> {
match self.with_connection(|conn| {
use crate::schema::benchmarks::dsl::*;
benchmarks.order(created_at.desc()).load::<Benchmark>(conn)
}) {
Ok(Ok(v)) => Ok(json!(v)),
Ok(Err(e)) => Err(e.into()),
Err(e) => Err(e.into()),
}
}
fn get_targets(&self, id: i32) -> Result<Value, Error> {
match self.with_connection(|conn| {
let query = sql_query(
"SELECT DISTINCT logs->>'target' as target from tetcore_logs \
WHERE logs->>'target' IS NOT NULL \
AND peer_connection_id = ANY (\
SELECT id from peer_connections WHERE peer_id = \
(SELECT setup->'tetcore'->>'peerId' as peer_id FROM benchmarks WHERE id = $1)\
) ORDER BY target ASC",
)
.bind::<Integer, _>(id);
debug!(
"get_targets query: {}",
diesel::debug_query::<diesel::pg::Pg, _>(&query)
);
let result: QueryResult<Vec<Targets>> = query.get_results(conn);
result
}) {
Ok(Ok(v)) => Ok(json!(v)),
Ok(Err(e)) => Err(e.into()),
Err(e) => Err(e.into()),
}
}
fn get_events(&self, bm_id: i32) -> Result<Value, Error> {
match self.with_connection(|conn| {
use crate::schema::benchmark_events::dsl::*;
benchmark_events
.filter(benchmark_id.eq(bm_id))
.order(name.asc())
.load::<BenchmarkEvent>(conn)
}) {
Ok(Ok(v)) => Ok(json!(v)),
Ok(Err(e)) => Err(e.into()),
Err(e) => Err(e.into()),
}
}
fn save_benchmark(&self, msg: NewBenchmark) -> Result<Value, Error> {
match self.with_connection(|conn| {
use crate::schema::benchmarks;
diesel::insert_into(benchmarks::table)
.values(msg)
.get_result::<Benchmark>(conn)
}) {
Ok(Ok(v)) => Ok(json!(v)),
Ok(Err(e)) => Err(e.into()),
Err(e) => Err(e.into()),
}
}
fn save_benchmark_event(&self, msg: NewBenchmarkEvent) -> Result<Value, Error> {
match self.with_connection(|conn| {
use crate::schema::benchmark_events;
diesel::insert_into(benchmark_events::table)
.values(msg)
.get_result::<BenchmarkEvent>(conn)
}) {
Ok(Ok(v)) => Ok(json!(v)),
Ok(Err(e)) => Err(e.into()),
Err(e) => Err(e.into()),
}
}
}
impl NewBenchmark {
pub fn example() -> Self {
NewBenchmark {
setup: serde_json::Value::default(),
}
}
}