Skip to content

Commit

Permalink
Merge pull request #102 from lajp/database-refactor
Browse files Browse the repository at this point in the history
perf: use diesel_async and improve queries
  • Loading branch information
lajp authored Dec 27, 2023
2 parents 8e9ee0e + 7b23ef1 commit 6239da7
Show file tree
Hide file tree
Showing 12 changed files with 1,423 additions and 1,101 deletions.
1,244 changes: 771 additions & 473 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ regex = "1.5"
tracing = "0.1.37"
tracing-actix-web = "0.6.2"

diesel = { version = "2.1.0", features = ["postgres", "chrono", "r2d2", "serde_json"] }
r2d2 = "0.8"

log = "0.4"
Expand All @@ -45,3 +44,5 @@ url = "2.2"

itertools = "0.10.3"
governor = "0.6.0"
diesel = { version = "2.1.0", features = ["chrono", "serde_json"] }
diesel-async = { version = "0.4.1", features = ["postgres", "deadpool"] }
97 changes: 53 additions & 44 deletions src/database/activity.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use chrono::{prelude::*, Duration};
use diesel::prelude::*;
use diesel_async::RunQueryDsl;

use crate::{
error::TimeError,
Expand All @@ -19,40 +20,32 @@ impl super::DatabaseWrapper {
user_id: updated_user_id,
start_time: ctx_start_time,
duration: ctx_duration.num_seconds() as i32,
project_name: if heartbeat.project_name.is_some()
&& heartbeat.project_name.as_ref().unwrap().starts_with("tmp.")
{
Some(String::from("tmp"))
} else {
heartbeat.project_name.map(|s| s.to_lowercase())
},
project_name: heartbeat.project_name,
language: heartbeat.language,
editor_name: heartbeat.editor_name,
hostname: heartbeat.hostname,
};

self.run_async_query(move |mut conn| {
use crate::schema::coding_activities::dsl::*;
let mut conn = self.db.get().await?;

diesel::insert_into(coding_activities)
.values(activity)
.execute(&mut conn)?;
use crate::schema::coding_activities::dsl::*;

Ok(())
})
.await?;
diesel::insert_into(coding_activities)
.values(activity)
.execute(&mut conn)
.await?;

Ok(())
}

pub async fn get_all_activity(&self, user: i32) -> Result<Vec<CodingActivity>, TimeError> {
self.run_async_query(move |mut conn| {
use crate::schema::coding_activities::dsl::*;
Ok(coding_activities
.filter(user_id.eq(user))
.load::<CodingActivity>(&mut conn)?)
})
.await
let mut conn = self.db.get().await?;

use crate::schema::coding_activities::dsl::*;
Ok(coding_activities
.filter(user_id.eq(user))
.load::<CodingActivity>(&mut conn)
.await?)
}

pub async fn get_activity(
Expand Down Expand Up @@ -84,31 +77,34 @@ impl super::DatabaseWrapper {
query = query.filter(duration.ge(min_duration));
};

self.run_async_query(move |mut conn| Ok(query.load::<CodingActivity>(&mut conn)?))
.await
let mut conn = self.db.get().await?;
Ok(query.load::<CodingActivity>(&mut conn).await?)
}

pub async fn get_user_coding_time_since(
&self,
uid: i32,
since: chrono::NaiveDateTime,
) -> Result<i32, TimeError> {
self.run_async_query(move |mut conn| {
use crate::schema::coding_activities::dsl::*;

Ok(coding_activities
.filter(user_id.eq(uid).and(start_time.ge(since)))
.select(diesel::dsl::sum(duration))
.first::<Option<i64>>(&mut conn)?
.unwrap_or(0) as i32)
})
.await
let mut conn = self.db.get().await?;

use crate::schema::coding_activities::dsl::*;

Ok(coding_activities
.filter(user_id.eq(uid).and(start_time.ge(since)))
.select(diesel::dsl::sum(duration))
.first::<Option<i64>>(&mut conn)
.await?
.unwrap_or(0) as i32)
}

pub async fn get_coding_time_steps(&self, uid: i32) -> CodingTimeSteps {
CodingTimeSteps {
all_time: self
.get_user_coding_time_since(uid, chrono::NaiveDateTime::from_timestamp(0, 0))
.get_user_coding_time_since(
uid,
chrono::NaiveDateTime::from_timestamp_opt(0, 0).unwrap(),
)
.await
.unwrap_or(0),
past_month: self
Expand All @@ -134,14 +130,27 @@ impl super::DatabaseWrapper {
from: String,
to: String,
) -> Result<usize, TimeError> {
self.run_async_query(move |mut conn| {
use crate::schema::coding_activities::dsl::*;
Ok(diesel::update(coding_activities)
.filter(user_id.eq(target_user_id))
.filter(project_name.eq(from))
.set(project_name.eq(to))
.execute(&mut conn)?)
})
.await
let mut conn = self.db.get().await?;

use crate::schema::coding_activities::dsl::*;
Ok(diesel::update(coding_activities)
.filter(user_id.eq(target_user_id))
.filter(project_name.eq(from))
.set(project_name.eq(to))
.execute(&mut conn)
.await?)
}

pub async fn delete_activity(&self, userid: i32, activity: i32) -> Result<bool, TimeError> {
let mut conn = self.db.get().await?;

use crate::schema::coding_activities::dsl::*;

Ok(diesel::delete(coding_activities.find(activity))
// FIXME: This filter is useless?
.filter(user_id.eq(userid))
.execute(&mut conn)
.await?
!= 0)
}
}
Loading

0 comments on commit 6239da7

Please sign in to comment.