Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@
*.db
*.db-wal
*.db-shm
/.direnv
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions database/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ sqlx = { version = "0.8.6", default-features = false, features = [
"sqlite",
"migrate",
"macros",
"chrono"
] }
rand = {version = "0.9.2", default-features = false}
base-62 = {version = "0.1.1", default-features = false}
2 changes: 1 addition & 1 deletion database/src/models/achievement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub struct AchievementGoalUnlock {
pub goal_id: i32,
pub goal_description: String,
pub goal_sequence: i32,
pub unlocked_at: Option<DateTime<Local>>,
pub time: DateTime<Local>,
}

#[derive(Serialize, Deserialize)]
Expand Down
117 changes: 115 additions & 2 deletions database/src/repos/achievement.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use sqlx::{SqlitePool, query, query_as};
use sqlx::{SqlitePool, query, query_as, query_scalar};

use crate::{
error::DatabaseError,
models::achievement::{Achievement, AchievementCreate, AchievementGoal},
models::achievement::{Achievement, AchievementCreate, AchievementGoal, AchievementGoalUnlock},
};

pub struct AchievementRepo<'a> {
Expand Down Expand Up @@ -40,6 +40,36 @@ impl<'a> AchievementRepo<'a> {
.await?)
}

pub async fn by_unlocked_goal_id(
&self,
user_id: u32,
goal_id: u32,
) -> Result<Vec<AchievementGoalUnlock>, DatabaseError> {
Ok(query_as(
"
SELECT
achievement.id as achievement_id,
achievement.name as achievement_name,
service_id,
goal.id as goal_id,
goal.description as goal_description,
goal.sequence as goal_sequence,
time
FROM
goal as goal1
INNER JOIN achievement on achievement.id = goal1.achievement_id
INNER JOIN goal on goal.achievement_id = achievement.id
INNER JOIN unlock on goal1.id = unlock.goal_id
WHERE
goal1.id = ? AND user_id = ?;
",
)
.bind(goal_id)
.bind(user_id)
.fetch_all(self.db)
.await?)
}

pub async fn for_service(
&self,
service_id: u32,
Expand Down Expand Up @@ -119,4 +149,87 @@ impl<'a> AchievementRepo<'a> {
tx.commit().await?;
self.by_id(db_achievement.id).await
}

pub async fn unlock_goal(
&self,
user_id: u32,
goal_id: u32,
) -> Result<Vec<AchievementGoalUnlock>, DatabaseError> {
query(
"
INSERT INTO
unlock (user_id, goal_id)
VALUES
(?,?);
",
)
.bind(user_id)
.bind(goal_id)
.execute(self.db)
.await?;

self.by_unlocked_goal_id(user_id, goal_id).await
}

pub async fn goal_exist(&self, goal_id: u32) -> Result<bool, DatabaseError> {
Ok(query_scalar::<_, i32>(
"
SELECT
1
FROM
goal
WHERE
goal.id = ?;
",
)
.bind(goal_id)
.fetch_optional(self.db)
.await?
.is_some())
}

pub async fn goal_unlocked(&self, goal_id: u32) -> Result<bool, DatabaseError> {
Ok(query_scalar::<_, i32>(
"
SELECT
1
FROM
unlock
WHERE
goal_id = ?;
",
)
.bind(goal_id)
.fetch_optional(self.db)
.await?
.is_some())
}

pub async fn unlocked_for_user(
&self,
user_id: u32,
) -> Result<Vec<AchievementGoalUnlock>, DatabaseError> {
Ok(query_as(
"SELECT
achievement.id as achievement_id,
name as achievement_name,
service_id,
goal.id as goal_id,
description as goal_description,
sequence as goal_sequence,
time
FROM
unlock
INNER JOIN goal ON goal_id = goal.id
INNER JOIN achievement ON achievement_id = achievement.id
WHERE
user_id = ?
ORDER BY
achievement_id, goal_sequence;
",
)
.bind(user_id)
.fetch_all(self.db)
.await?)
}
}
8 changes: 8 additions & 0 deletions database/src/repos/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,12 @@ impl<'a> ServiceRepo<'a> {
.await?
.ok_or(DatabaseError::NotFound)
}

pub async fn by_id(&self, id: u32) -> Result<Service, DatabaseError> {
sqlx::query_as("SELECT id, name, api_key FROM service WHERE id == ? LIMIT 1;")
.bind(id)
.fetch_optional(self.db)
.await?
.ok_or(DatabaseError::NotFound)
}
}
Loading