Skip to content

Commit

Permalink
feat: newer grades and parameterized queries (#238)
Browse files Browse the repository at this point in the history
previously, we were using template strings,
which had issues for professors with an apostrophe in their name
  • Loading branch information
Samathingamajig authored Sep 30, 2024
1 parent f34dd95 commit 75ad416
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 17 deletions.
Binary file modified public/database/grade_distributions.db
Binary file not shown.
54 changes: 37 additions & 17 deletions src/views/lib/database/queryDistribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ import type { CourseSQLRow, Distribution } from '@shared/types/Distribution';

import { initializeDB } from './initializeDB';

type GradeDistributionParams = {
':department_code': string;
':course_number': string;
':instructor_last'?: string;
':semester'?: string;
};

/**
* fetches the aggregate distribution of grades for a given course from the course db, and the semesters that we have data for
* @param course the course to fetch the distribution for
Expand All @@ -11,14 +18,14 @@ import { initializeDB } from './initializeDB';
*/
export async function queryAggregateDistribution(course: Course): Promise<[Distribution, Semester[], boolean]> {
const db = await initializeDB();
const query = generateQuery(course, null, true);
const [query, params] = generateQuery(course, null, true);

let res = db.exec(query)?.[0];
let res = db.exec(query, params)?.[0];
let instructorIncluded = true;
if (!res?.columns?.length) {
instructorIncluded = false;
const queryWithoutInstructor = generateQuery(course, null, false);
res = db.exec(queryWithoutInstructor)?.[0];
const [queryWithoutInstructor, paramsWithoutInstructor] = generateQuery(course, null, false);
res = db.exec(queryWithoutInstructor, paramsWithoutInstructor)?.[0];

if (!res?.columns?.length) {
throw new NoDataError(course);
Expand Down Expand Up @@ -87,20 +94,33 @@ export async function queryAggregateDistribution(course: Course): Promise<[Distr
* @param semester the semester to fetch the distribution for OR null if we want the aggregate distribution
* @returns a SQL query string
*/
function generateQuery(course: Course, semester: Semester | null, includeInstructor: boolean): string {
const profName = course.instructors[0]?.lastName;

function generateQuery(
course: Course,
semester: Semester | null,
includeInstructor: boolean
): [string, GradeDistributionParams] {
const query = `
select * from grade_distributions
where Department_Code = '${course.department}'
and Course_Number = '${course.number}'
${includeInstructor ? `and Instructor_Last = '${profName}' collate nocase` : ''}
${semester ? `and Semester = '${semester.season} ${semester.year}'` : ''}
where Department_Code = :department_code
and Course_Number = :course_number
${includeInstructor ? `and Instructor_Last = :instructor_last collate nocase` : ''}
${semester ? `and Semester = :semester` : ''}
`;

console.log(includeInstructor, { query });
const params: GradeDistributionParams = {
':department_code': course.department,
':course_number': course.number,
};

if (includeInstructor) {
params[':instructor_last'] = course.instructors[0]?.lastName;
}

if (semester) {
params[':semester'] = `${semester.season} ${semester.year}`;
}

return query;
return [query, params];
}

/**
Expand All @@ -111,14 +131,14 @@ function generateQuery(course: Course, semester: Semester | null, includeInstruc
*/
export async function querySemesterDistribution(course: Course, semester: Semester): Promise<[Distribution, boolean]> {
const db = await initializeDB();
const query = generateQuery(course, semester, true);
const [query, params] = generateQuery(course, semester, true);

let res = db.exec(query)?.[0];
let res = db.exec(query, params)?.[0];
let instructorIncluded = true;
if (!res?.columns?.length) {
instructorIncluded = false;
const queryWithoutInstructor = generateQuery(course, semester, false);
res = db.exec(queryWithoutInstructor)?.[0];
const [queryWithoutInstructor, paramsWithoutInstructor] = generateQuery(course, semester, false);
res = db.exec(queryWithoutInstructor, paramsWithoutInstructor)?.[0];
if (!res?.columns?.length) {
throw new NoDataError(course);
}
Expand Down

0 comments on commit 75ad416

Please sign in to comment.