Skip to content

Commit b234700

Browse files
committed
add projects feature
1 parent 356e508 commit b234700

File tree

8 files changed

+92
-4
lines changed

8 files changed

+92
-4
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CREATE TABLE Project (
2+
project_id SERIAL PRIMARY KEY,
3+
member_id INT NOT NULL,
4+
title TEXT,
5+
CONSTRAINT fkey_member FOREIGN KEY (member_id) REFERENCES Member(member_id) ON DELETE CASCADE
6+
);

src/graphql/mod.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
use async_graphql::MergedObject;
2-
use mutations::{AttendanceMutations, MemberMutations, StreakMutations};
3-
use queries::{AttendanceQueries, MemberQueries, StreakQueries};
2+
use mutations::{AttendanceMutations, MemberMutations, ProjectMutations, StreakMutations};
3+
use queries::{AttendanceQueries, MemberQueries, ProjectQueries, StreakQueries};
44

55
pub mod mutations;
66
pub mod queries;
77

88
// This is our main query or QueryRoot. It is made up of structs representing sub-queries, one for each table in the DB. The fields of a relation are exposed via the [`async_graphql::SimpleObject`] directive on the [`models`] themselves. Specific queries, such as getting a member by ID or getting the streak of a member is defined as methods of the sub-query struct. Complex queries, such as those getting related data from multiple tables like querying all members and the streaks of each member, are defined via the [`async_graphql::ComplexObject`] directive on the [`models`] and can be found in the corresponding sub-query module.
99
#[derive(MergedObject, Default)]
10-
pub struct Query(MemberQueries, AttendanceQueries, StreakQueries);
10+
pub struct Query(
11+
MemberQueries,
12+
AttendanceQueries,
13+
StreakQueries,
14+
ProjectQueries,
15+
);
1116

1217
// Mutations work the same as Queries, sub-modules for each relation in the DB. However, all methods are directly defined on these sub-module structs. But they use slightly modified versions of the [`models`], marked by the Input in the name, to get input.
1318
#[derive(MergedObject, Default)]
14-
pub struct Mutation(MemberMutations, AttendanceMutations, StreakMutations);
19+
pub struct Mutation(
20+
MemberMutations,
21+
AttendanceMutations,
22+
StreakMutations,
23+
ProjectMutations,
24+
);

src/graphql/mutations/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
pub mod attendance_mutations;
22
pub mod member_mutations;
3+
pub mod project_mutations;
34
pub mod streak_mutations;
45

56
pub use attendance_mutations::AttendanceMutations;
67
pub use member_mutations::MemberMutations;
8+
pub use project_mutations::ProjectMutations;
79
pub use streak_mutations::StreakMutations;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use std::sync::Arc;
2+
3+
use async_graphql::{Context, Error, Object, Result};
4+
use sqlx::PgPool;
5+
6+
use crate::models::project::{Project, SetProjectInput};
7+
8+
#[derive(Default)]
9+
pub struct ProjectMutations;
10+
11+
#[Object]
12+
impl ProjectMutations {
13+
#[graphql(name = "setProject")]
14+
// input is member_id
15+
async fn set_project(&self, ctx: &Context<'_>, input: SetProjectInput) -> Result<Project> {
16+
let pool = ctx
17+
.data::<Arc<PgPool>>()
18+
.expect("Pool must be found in context");
19+
20+
let project = sqlx::query_as::<_, Project>(
21+
"INSERT INTO Project (member_id, project_title) VALUES ($1, $2) RETURNING * ",
22+
)
23+
.bind(input.member_id)
24+
.bind(input.title)
25+
.fetch_one(pool.as_ref())
26+
.await?;
27+
Ok(project)
28+
}
29+
}

src/graphql/queries/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
pub mod attendance_queries;
22
pub mod member_queries;
3+
pub mod project_queries;
34
pub mod streak_queries;
45

56
pub use attendance_queries::AttendanceQueries;
67
pub use member_queries::MemberQueries;
8+
pub use project_queries::ProjectQueries;
79
pub use streak_queries::StreakQueries;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use std::sync::Arc;
2+
3+
use crate::models::project::Project;
4+
use async_graphql::{Context, Object, Result};
5+
use sqlx::PgPool;
6+
7+
/// Sub-query for the [`Project`] table. The queries are:
8+
/// * projects - get all projects
9+
#[derive(Default)]
10+
pub struct ProjectQueries;
11+
12+
#[Object]
13+
impl ProjectQueries {
14+
pub async fn projects(&self, ctx: &Context<'_>) -> Result<Vec<Project>> {
15+
let pool = ctx.data::<Arc<PgPool>>().expect("Pool must be in context.");
16+
17+
let projects = sqlx::query_as::<_, Project>("SELECT * FROM Project")
18+
.fetch_all(pool.as_ref())
19+
.await?;
20+
21+
Ok(projects)
22+
}
23+
}

src/models/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod attendance;
22
pub mod member;
3+
pub mod project;
34
pub mod status_update_streak;

src/models/project.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use async_graphql::{InputObject, SimpleObject};
2+
use sqlx::FromRow;
3+
4+
#[derive(FromRow, SimpleObject)]
5+
pub struct Project {
6+
pub project_id: i32,
7+
pub member_id: i32,
8+
pub title: Option<String>,
9+
}
10+
11+
#[derive(InputObject)]
12+
pub struct SetProjectInput {
13+
pub member_id: i32,
14+
pub title: String,
15+
}

0 commit comments

Comments
 (0)