diff --git a/src/db/README.md b/src/db/README.md index 118f5ae..f9be111 100644 --- a/src/db/README.md +++ b/src/db/README.md @@ -129,5 +129,5 @@ verification step is considered successful if it completes without any error. imported: ```sql -SELECT * FROM Gradebook.getAttendance(2017, 'Spring', 'CS110', '5'); +SELECT * FROM getAttendance(2017, 'Spring', 'CS110', '5'); ``` diff --git a/src/db/addAttendanceMgmt.sql b/src/db/addAttendanceMgmt.sql index a3ac8a9..597fa2c 100644 --- a/src/db/addAttendanceMgmt.sql +++ b/src/db/addAttendanceMgmt.sql @@ -21,7 +21,7 @@ SET LOCAL client_min_messages TO WARNING; --Drop function from M1 that has since been renamed or removed -- remove the DROP statement after M2 -DROP FUNCTION IF EXISTS Gradebook.datesFromSchedule(DATE, DATE, VARCHAR(7)); +DROP FUNCTION IF EXISTS datesFromSchedule(DATE, DATE, VARCHAR(7)); --Function to generate a list of dates for a class schedule, within a date range @@ -38,11 +38,11 @@ DROP FUNCTION IF EXISTS Gradebook.datesFromSchedule(DATE, DATE, VARCHAR(7)); --S = Saturday --Example usage: get dates of Tuesdays and Thursdays b/w 2017-01-01 and 2017-05-01: --- SELECT * FROM Gradebook.getScheduleDates('2017-01-01', '2017-05-01', 'TR'); +-- SELECT * FROM getScheduleDates('2017-01-01', '2017-05-01', 'TR'); -DROP FUNCTION IF EXISTS Gradebook.getScheduleDates(DATE, DATE, VARCHAR(7)); +DROP FUNCTION IF EXISTS getScheduleDates(DATE, DATE, VARCHAR(7)); -CREATE FUNCTION Gradebook.getScheduleDates(startDate DATE, endDate DATE, +CREATE FUNCTION getScheduleDates(startDate DATE, endDate DATE, schedule VARCHAR(7) ) RETURNS TABLE (ScheduleDate DATE) @@ -76,9 +76,9 @@ $$ LANGUAGE sql --Function to get attendance for a section ID -DROP FUNCTION IF EXISTS Gradebook.getAttendance(INT); +DROP FUNCTION IF EXISTS getAttendance(INT); -CREATE FUNCTION Gradebook.getAttendance(sectionID INT) +CREATE FUNCTION getAttendance(sectionID INT) RETURNS TABLE(AttendanceCsvWithHeader TEXT) AS $$ @@ -87,15 +87,15 @@ $$ SectionDate AS ( SELECT ScheduleDate - FROM Gradebook.Section, - Gradebook.getScheduleDates(StartDate, EndDate, Schedule) + FROM Section, + getScheduleDates(StartDate, EndDate, Schedule) WHERE ID = $1 ), --combine every student enrolled in section w/ each meeting date of section Enrollee_Date AS ( SELECT Student, ScheduleDate - FROM Gradebook.Enrollee, SectionDate + FROM Enrollee, SectionDate WHERE Section = $1 ), --get the recorded attendance for each enrollee, marking as "Present" if @@ -104,7 +104,7 @@ $$ ( SELECT ed.Student, ScheduleDate, COALESCE(ar.Status, 'P') c FROM Enrollee_Date ed - LEFT OUTER JOIN Gradebook.AttendanceRecord ar + LEFT OUTER JOIN AttendanceRecord ar ON ed.Student = ar.Student AND ed.ScheduleDate = ar.Date AND ar.Section = $1 --can't move test on section to WHERE clause @@ -124,7 +124,7 @@ $$ SELECT concat_ws(',', st.LName, st.FName, COALESCE(st.MName, ''), string_agg(c, ',' ORDER BY ScheduleDate) ) - FROM sdar JOIN Gradebook.Student st ON sdar.Student = st.ID + FROM sdar JOIN Student st ON sdar.Student = st.ID GROUP BY st.ID ORDER BY st.LName, st.FName, COALESCE(st.MName, '') ); @@ -133,16 +133,16 @@ $$ LANGUAGE sql; --Function to get attendance for a year-season-course-section# combo -DROP FUNCTION IF EXISTS Gradebook.getAttendance(NUMERIC(4,0), VARCHAR(20), +DROP FUNCTION IF EXISTS getAttendance(NUMERIC(4,0), VARCHAR(20), VARCHAR(8), VARCHAR(3) ); -CREATE FUNCTION Gradebook.getAttendance(year NUMERIC(4,0), +CREATE FUNCTION getAttendance(year NUMERIC(4,0), seasonIdentification VARCHAR(20), course VARCHAR(8), sectionNumber VARCHAR(3) ) RETURNS TABLE(AttendanceCsvWithHeader TEXT) AS $$ - SELECT Gradebook.getAttendance(Gradebook.getSectionID($1, $2, $3, $4)); + SELECT getAttendance(getSectionID($1, $2, $3, $4)); $$ LANGUAGE sql; diff --git a/src/db/addInstructorMgmt.sql b/src/db/addInstructorMgmt.sql index 20e1d1e..7ad8987 100644 --- a/src/db/addInstructorMgmt.sql +++ b/src/db/addInstructorMgmt.sql @@ -18,9 +18,9 @@ --Function to get details of all known instructors -DROP FUNCTION IF EXISTS Gradebook.getInstructors(); +DROP FUNCTION IF EXISTS getInstructors(); -CREATE FUNCTION Gradebook.getInstructors() +CREATE FUNCTION getInstructors() RETURNS TABLE ( ID INT, @@ -34,7 +34,7 @@ AS $$ SELECT ID, FName, MName, LName, Department, Email - FROM Gradebook.Instructor; + FROM Instructor; $$ LANGUAGE sql STABLE; --no need for RETURN NULL ON... because the function takes no input @@ -43,9 +43,9 @@ $$ LANGUAGE sql --function to get details of the instructor with the given e-mail address -- performs a case-insensitive match of email address; -- returns 0 or 1 row: Instructor.Email is unique; -DROP FUNCTION IF EXISTS Gradebook.getInstructor(Gradebook.Instructor.Email%TYPE); +DROP FUNCTION IF EXISTS getInstructor(Gradebook.Instructor.Email%TYPE); -CREATE FUNCTION Gradebook.getInstructor(Email Gradebook.Instructor.Email%TYPE) +CREATE FUNCTION getInstructor(Email Instructor.Email%TYPE) RETURNS TABLE ( ID INT, @@ -58,7 +58,7 @@ AS $$ SELECT ID, FName, MName, LName, Department - FROM Gradebook.Instructor + FROM Instructor WHERE LOWER(TRIM(Email)) = LOWER(TRIM($1)); $$ LANGUAGE sql @@ -68,9 +68,9 @@ $$ LANGUAGE sql --function to get details of the instructor with the given ID -DROP FUNCTION IF EXISTS Gradebook.getInstructor(INT); +DROP FUNCTION IF EXISTS getInstructor(INT); -CREATE FUNCTION Gradebook.getInstructor(instructorID INT) +CREATE FUNCTION getInstructor(instructorID INT) RETURNS TABLE ( FName VARCHAR(50), @@ -83,7 +83,7 @@ AS $$ SELECT FName, MName, LName, Department, Email - FROM Gradebook.Instructor + FROM Instructor WHERE ID = $1; $$ LANGUAGE sql @@ -94,24 +94,24 @@ $$ LANGUAGE sql --drop functions with older names due to names being revised -- remove this block of code after milestone M1 -DROP FUNCTION IF EXISTS Gradebook.getYears(INT); -DROP FUNCTION IF EXISTS Gradebook.getSeasons(INT, NUMERIC(4,0)); -DROP FUNCTION IF EXISTS Gradebook.getCourses(INT, NUMERIC(4,0), NUMERIC(1,0)); -DROP FUNCTION IF EXISTS Gradebook.getSections(INT, NUMERIC(4,0), +DROP FUNCTION IF EXISTS getYears(INT); +DROP FUNCTION IF EXISTS getSeasons(INT, NUMERIC(4,0)); +DROP FUNCTION IF EXISTS getCourses(INT, NUMERIC(4,0), NUMERIC(1,0)); +DROP FUNCTION IF EXISTS getSections(INT, NUMERIC(4,0), NUMERIC(1,0), VARCHAR(8) ); --function to get the years in which an instructor has taught -DROP FUNCTION IF EXISTS Gradebook.getInstructorYears(INT); +DROP FUNCTION IF EXISTS getInstructorYears(INT); -CREATE FUNCTION Gradebook.getInstructorYears(instructorID INT) +CREATE FUNCTION getInstructorYears(instructorID INT) RETURNS TABLE(Year NUMERIC(4,0)) AS $$ SELECT DISTINCT Year - FROM Gradebook.Term T JOIN Gradebook.Section N ON T.ID = N.Term + FROM Term T JOIN Section N ON T.ID = N.Term WHERE $1 IN (N.Instructor1, N.Instructor2, N.Instructor3) ORDER BY Year DESC; @@ -121,9 +121,9 @@ $$ LANGUAGE sql --function to get all seasons an instructor has taught in a specfied year -DROP FUNCTION IF EXISTS Gradebook.getInstructorSeasons(INT, NUMERIC(4,0)); +DROP FUNCTION IF EXISTS getInstructorSeasons(INT, NUMERIC(4,0)); -CREATE FUNCTION Gradebook.getInstructorSeasons(instructorID INT, +CREATE FUNCTION getInstructorSeasons(instructorID INT, year NUMERIC(4,0) ) RETURNS TABLE(SeasonOrder NUMERIC(1,0), SeasonName VARCHAR(20)) @@ -131,8 +131,8 @@ AS $$ SELECT DISTINCT S."Order", S.Name - FROM Gradebook.Season S JOIN Gradebook.Term T ON S."Order" = T.Season - JOIN Gradebook.Section N ON N.Term = T.ID + FROM Season S JOIN Term T ON S."Order" = T.Season + JOIN Section N ON N.Term = T.ID WHERE $1 IN (N.Instructor1, N.Instructor2, N.Instructor3) AND T.Year = $2 ORDER BY S."Order"; @@ -143,11 +143,11 @@ $$ LANGUAGE sql --function to get all courses an instructor has taught in a year-season combo -DROP FUNCTION IF EXISTS Gradebook.getInstructorCourses(INT, NUMERIC(4,0), +DROP FUNCTION IF EXISTS getInstructorCourses(INT, NUMERIC(4,0), NUMERIC(1,0) ); -CREATE FUNCTION Gradebook.getInstructorCourses(instructorID INT, +CREATE FUNCTION getInstructorCourses(instructorID INT, year NUMERIC(4,0), seasonOrder NUMERIC(1,0) ) @@ -156,7 +156,7 @@ AS $$ SELECT DISTINCT N.Course - FROM Gradebook.Section N JOIN Gradebook.Term T ON N.Term = T.ID + FROM Section N JOIN Term T ON N.Term = T.ID WHERE $1 IN (N.Instructor1, N.Instructor2, N.Instructor3) AND T.Year = $2 AND T.Season = $3 @@ -173,11 +173,11 @@ $$ LANGUAGE sql -- a string of the form "course-sectionNumber"; --this function is useful in showing Course-Section combinations directly --without having to first explicitly choose a course to get sections -DROP FUNCTION IF EXISTS Gradebook.getInstructorSections(INT, NUMERIC(4,0), +DROP FUNCTION IF EXISTS getInstructorSections(INT, NUMERIC(4,0), NUMERIC(1,0) ); -CREATE FUNCTION Gradebook.getInstructorSections(instructorID INT, +CREATE FUNCTION getInstructorSections(instructorID INT, year NUMERIC(4,0), seasonOrder NUMERIC(1,0) ) @@ -191,7 +191,7 @@ $$ SELECT N.ID, N.Course, N.SectionNumber, N.Course || '-' || N.SectionNumber AS CourseSection - FROM Gradebook.Section N JOIN Gradebook.Term T ON N.Term = T.ID + FROM Section N JOIN Term T ON N.Term = T.ID WHERE $1 IN (N.Instructor1, N.Instructor2, N.Instructor3) AND T.Year = $2 AND T.Season = $3 @@ -203,11 +203,11 @@ $$ LANGUAGE sql --function to get the section number(s) of a course an instructor has taught -- performs case-insensitive match for course -DROP FUNCTION IF EXISTS Gradebook.getInstructorSections(INT, NUMERIC(4,0), +DROP FUNCTION IF EXISTS getInstructorSections(INT, NUMERIC(4,0), NUMERIC(1,0), VARCHAR(8) ); -CREATE FUNCTION Gradebook.getInstructorSections(instructorID INT, +CREATE FUNCTION getInstructorSections(instructorID INT, year NUMERIC(4,0), seasonOrder NUMERIC(1,0), courseNumber VARCHAR(8) @@ -217,7 +217,7 @@ AS $$ SELECT SectionID, SectionNumber - FROM Gradebook.getInstructorSections($1, $2, $3) + FROM getInstructorSections($1, $2, $3) WHERE LOWER(Course) = LOWER($4) ORDER BY SectionNumber; diff --git a/src/db/addReferenceData.sql b/src/db/addReferenceData.sql index 9567db5..4f9effb 100644 --- a/src/db/addReferenceData.sql +++ b/src/db/addReferenceData.sql @@ -24,7 +24,7 @@ -- in the calendar year; not in the school's academic year. For example, the -- rows inserted here say that Spring is the first season classes are held in a -- calendar year, followed by "Spring_Break" and so on -INSERT INTO Gradebook.Season("Order", Name, Code) +INSERT INTO Season("Order", Name, Code) VALUES ('0','Spring','S'), ('1','Spring_Break','B'), ('2','Summer','M'), ('3','Fall','F'), ('4','Intersession','I'); @@ -33,8 +33,8 @@ VALUES --populate the Grade table with values used at most US schools -- each record establishes a correspondence between a letter grade and eqt. GPA; --- see schema of Gradebook.Grade for values permitted in these columns -INSERT INTO Gradebook.Grade(Letter, GPA) +-- see schema of Grade for values permitted in these columns +INSERT INTO Grade(Letter, GPA) VALUES ('A+', 4.333), ('A', 4), ('A-', 3.667), ('B+', 3.333), ('B', 3), ('B-', 2.667), ('C+', 2.333), ('C', 2), ('C-', 1.667), ('D+', 1.333), @@ -45,7 +45,7 @@ VALUES --add some well-known attendance statuses -- each record creates a correspondence between an internal status code and a -- description that is displayed to the user -INSERT INTO Gradebook.AttendanceStatus(Status, Description) +INSERT INTO AttendanceStatus(Status, Description) VALUES ('P', 'Present'), ('A', 'Absent'), ('E', 'Explained'), ('S', 'Stopped Attending'), ('X', 'Excused'), ('N', 'Not Registered'), diff --git a/src/db/addSeasonMgmt.sql b/src/db/addSeasonMgmt.sql index 12a743d..1a1553f 100644 --- a/src/db/addSeasonMgmt.sql +++ b/src/db/addSeasonMgmt.sql @@ -22,9 +22,9 @@ SET LOCAL client_min_messages TO WARNING; -- performs case-insensitive match of season name and code -- this function makes it easier for users to indicate a season by any of the -- three possible identifiers for seasons -DROP FUNCTION IF EXISTS Gradebook.getSeason(VARCHAR(20)); +DROP FUNCTION IF EXISTS getSeason(VARCHAR(20)); -CREATE FUNCTION Gradebook.getSeason(seasonIdentification VARCHAR(20)) +CREATE FUNCTION getSeason(seasonIdentification VARCHAR(20)) RETURNS TABLE ( "Order" NUMERIC(1,0), @@ -35,7 +35,7 @@ AS $$ SELECT "Order", Name, Code - FROM Gradebook.Season + FROM Season WHERE CASE WHEN $1 ~ '^[0-9]$' THEN "Order" = to_number($1,'9') WHEN LENGTH($1) = 1 THEN Code = UPPER($1) @@ -50,9 +50,9 @@ $$ LANGUAGE sql --Function to get the details of the season matching a season order -- this function exists to support clients that pass season order as a number -DROP FUNCTION IF EXISTS Gradebook.getSeason(NUMERIC(1,0)); +DROP FUNCTION IF EXISTS getSeason(NUMERIC(1,0)); -CREATE FUNCTION Gradebook.getSeason(seasonOrder NUMERIC(1,0)) +CREATE FUNCTION getSeason(seasonOrder NUMERIC(1,0)) RETURNS TABLE ( "Order" NUMERIC(1,0), @@ -63,7 +63,7 @@ AS $$ SELECT "Order", Name, Code - FROM Gradebook.Season + FROM Season WHERE "Order" = $1; $$ LANGUAGE sql @@ -74,15 +74,15 @@ $$ LANGUAGE sql --Function to get the "order" of the season matching a "season identification" -DROP FUNCTION IF EXISTS Gradebook.getSeasonOrder(VARCHAR(20)); +DROP FUNCTION IF EXISTS getSeasonOrder(VARCHAR(20)); -CREATE FUNCTION Gradebook.getSeasonOrder(seasonIdentification VARCHAR(20)) +CREATE FUNCTION getSeasonOrder(seasonIdentification VARCHAR(20)) RETURNS NUMERIC(1,0) AS $$ SELECT "Order" - FROM Gradebook.getSeason($1); + FROM getSeason($1); $$ LANGUAGE sql STABLE diff --git a/src/db/addSectionMgmt.sql b/src/db/addSectionMgmt.sql index 9299885..d11fb9e 100644 --- a/src/db/addSectionMgmt.sql +++ b/src/db/addSectionMgmt.sql @@ -21,11 +21,11 @@ SET LOCAL client_min_messages TO WARNING; --Function to get ID of section matching a year-season-course-section# combo -- season is "season identification" -DROP FUNCTION IF EXISTS Gradebook.getSectionID(NUMERIC(4,0), VARCHAR(20), +DROP FUNCTION IF EXISTS getSectionID(NUMERIC(4,0), VARCHAR(20), VARCHAR(8), VARCHAR(3) ); -CREATE FUNCTION Gradebook.getSectionID(year NUMERIC(4,0), +CREATE FUNCTION getSectionID(year NUMERIC(4,0), seasonIdentification VARCHAR(20), course VARCHAR(8), sectionNumber VARCHAR(3) @@ -35,9 +35,9 @@ AS $$ SELECT N.ID - FROM Gradebook.Section N JOIN Gradebook.Term T ON N.Term = T.ID + FROM Section N JOIN Term T ON N.Term = T.ID WHERE T.Year = $1 - AND T.Season = Gradebook.getSeasonOrder($2) + AND T.Season = getSeasonOrder($2) AND LOWER(N.Course) = LOWER($3) AND LOWER(N.SectionNumber) = LOWER($4); @@ -50,11 +50,11 @@ $$ LANGUAGE sql -- season is "season order" -- reuses the season-identification version -- this function exists to support clients that pass season order as a number -DROP FUNCTION IF EXISTS Gradebook.getSectionID(NUMERIC(4,0), NUMERIC(1,0), +DROP FUNCTION IF EXISTS getSectionID(NUMERIC(4,0), NUMERIC(1,0), VARCHAR(8), VARCHAR(3) ); -CREATE FUNCTION Gradebook.getSectionID(year NUMERIC(4,0), +CREATE FUNCTION getSectionID(year NUMERIC(4,0), seasonOrder NUMERIC(1,0), course VARCHAR(8), sectionNumber VARCHAR(3) @@ -63,7 +63,7 @@ RETURNS INT AS $$ - SELECT Gradebook.getSectionID($1, $2::VARCHAR, $3, $4); + SELECT getSectionID($1, $2::VARCHAR, $3, $4); $$ LANGUAGE sql STABLE @@ -74,11 +74,11 @@ $$ LANGUAGE sql -- input season is "season identification" -- StartDate column contains term start date if section does not have start date; -- likewise with EndDate column -DROP FUNCTION IF EXISTS Gradebook.getSection(NUMERIC(4,0), VARCHAR(20), +DROP FUNCTION IF EXISTS getSection(NUMERIC(4,0), VARCHAR(20), VARCHAR(8), VARCHAR(3) ); -CREATE FUNCTION Gradebook.getSection(year NUMERIC(4,0), +CREATE FUNCTION getSection(year NUMERIC(4,0), seasonIdentification VARCHAR(20), course VARCHAR(8), sectionNumber VARCHAR(3) ) @@ -104,9 +104,9 @@ $$ SELECT N.ID, N.Term, N.Course, N.SectionNumber, N.CRN, N.Schedule, N.Location, COALESCE(N.StartDate, T.StartDate), COALESCE(N.EndDate, T.EndDate), N.MidtermDate, N.Instructor1, N.Instructor2, N.Instructor3 - FROM Gradebook.Section N JOIN Gradebook.Term T ON N.Term = T.ID + FROM Section N JOIN Term T ON N.Term = T.ID WHERE T.Year = $1 - AND T.Season = Gradebook.getSeasonOrder($2) + AND T.Season = getSeasonOrder($2) AND LOWER(N.Course) = LOWER($3) AND LOWER(N.SectionNumber) = LOWER($4); @@ -120,11 +120,11 @@ $$ LANGUAGE sql -- input season is "season order" -- reuses the season-identification version -- this function exists to support clients that pass season order as a number -DROP FUNCTION IF EXISTS Gradebook.getSection(NUMERIC(4,0), NUMERIC(1,0), +DROP FUNCTION IF EXISTS getSection(NUMERIC(4,0), NUMERIC(1,0), VARCHAR(8), VARCHAR(3) ); -CREATE FUNCTION Gradebook.getSection(year NUMERIC(4,0), seasonOrder NUMERIC(1,0), +CREATE FUNCTION getSection(year NUMERIC(4,0), seasonOrder NUMERIC(1,0), course VARCHAR(8), sectionNumber VARCHAR(3) ) RETURNS TABLE @@ -149,7 +149,7 @@ $$ SELECT ID, Term, Course, SectionNumber, CRN, Schedule, Location, StartDate, EndDate, MidtermDate, Instructor1, Instructor2, Instructor3 - FROM Gradebook.getSection($1, $2::VARCHAR, $3, $4); + FROM getSection($1, $2::VARCHAR, $3, $4); $$ LANGUAGE sql STABLE diff --git a/src/db/createTables.sql b/src/db/createTables.sql index 015103f..f2fc9ab 100644 --- a/src/db/createTables.sql +++ b/src/db/createTables.sql @@ -21,7 +21,7 @@ --This script assumes a schema named "Gradebook" already exists and is empty -CREATE TABLE Gradebook.Course +CREATE TABLE Course ( --Wonder if this table will eventually need a separate ID field Number VARCHAR(8) NOT NULL PRIMARY KEY, --e.g., 'CS170' @@ -29,7 +29,7 @@ CREATE TABLE Gradebook.Course ); -CREATE TABLE Gradebook.Season +CREATE TABLE Season ( --Order denotes the sequence of seasons within a year: 0, 1,...9 "Order" NUMERIC(1,0) PRIMARY KEY CHECK ("Order" >= 0), @@ -44,21 +44,21 @@ CREATE TABLE Gradebook.Season ); --enforce case-insensitive uniqueness of season name -CREATE UNIQUE INDEX idx_Unique_SeasonName ON Gradebook.Season(LOWER(TRIM(Name))); +CREATE UNIQUE INDEX idx_Unique_SeasonName ON Season(LOWER(TRIM(Name))); -CREATE TABLE Gradebook.Term +CREATE TABLE Term ( ID SERIAL NOT NULL PRIMARY KEY, Year NUMERIC(4,0) NOT NULL CHECK (Year > 0), --'2017' - Season NUMERIC(1,0) NOT NULL REFERENCES Gradebook.Season, + Season NUMERIC(1,0) NOT NULL REFERENCES Season, StartDate DATE NOT NULL, --date the term begins EndDate DATE NOT NULL, --date the term ends (last day of "finals" week) UNIQUE(Year, Season) ); -CREATE TABLE Gradebook.Instructor +CREATE TABLE Instructor ( ID SERIAL PRIMARY KEY, FName VARCHAR(50) NOT NULL, @@ -71,19 +71,19 @@ CREATE TABLE Gradebook.Instructor --enforce case-insensitive uniqueness of instructor e-mail addresses CREATE UNIQUE INDEX idx_Unique_InstructorEmail -ON Gradebook.Instructor(LOWER(TRIM(Email))); +ON Instructor(LOWER(TRIM(Email))); --Create a partial index on the instructor names. This enforces the CONSTRAINT -- that only one of any (FName, NULL, LName) is unique CREATE UNIQUE INDEX idx_Unique_Names_NULL -ON Gradebook.Instructor(FName, LName) +ON Instructor(FName, LName) WHERE MName IS NULL; -CREATE TABLE Gradebook.Section +CREATE TABLE Section ( ID SERIAL PRIMARY KEY, - Term INT NOT NULL REFERENCES Gradebook.Term, - Course VARCHAR(8) NOT NULL REFERENCES Gradebook.Course, + Term INT NOT NULL REFERENCES Term, + Course VARCHAR(8) NOT NULL REFERENCES Course, SectionNumber VARCHAR(3) NOT NULL, --'01', '72', etc. CRN VARCHAR(5) NOT NULL, --store this info for the registrar's benefit? Schedule VARCHAR(7), --days the class meets: 'MW', 'TR', 'MWF', etc. @@ -91,9 +91,9 @@ CREATE TABLE Gradebook.Section StartDate DATE, --first date the section meets EndDate DATE, --last date the section meets MidtermDate DATE, --date of the "middle" of term: used to compute mid-term grade - Instructor1 INT NOT NULL REFERENCES Gradebook.Instructor, --primary instructor - Instructor2 INT REFERENCES Gradebook.Instructor, --optional 2nd instructor - Instructor3 INT REFERENCES Gradebook.Instructor, --optional 3rd instructor + Instructor1 INT NOT NULL REFERENCES Instructor, --primary instructor + Instructor2 INT REFERENCES Instructor, --optional 2nd instructor + Instructor3 INT REFERENCES Instructor, --optional 3rd instructor UNIQUE(Term, Course, SectionNumber), --make sure instructors are distinct @@ -107,7 +107,7 @@ CREATE TABLE Gradebook.Section --Table to store all possible letter grades --some universities permit A+ -CREATE TABLE Gradebook.Grade +CREATE TABLE Grade ( Letter VARCHAR(2) NOT NULL PRIMARY KEY, GPA NUMERIC(4,3) NOT NULL, @@ -121,10 +121,10 @@ CREATE TABLE Gradebook.Grade --Table to store mapping of percentage score to a letter grade: varies by section -CREATE TABLE Gradebook.Section_GradeTier +CREATE TABLE Section_GradeTier ( - Section INT REFERENCES Gradebook.Section, - LetterGrade VARCHAR(2) NOT NULL REFERENCES Gradebook.Grade, + Section INT REFERENCES Section, + LetterGrade VARCHAR(2) NOT NULL REFERENCES Grade, LowPercentage NUMERIC(4,2) NOT NULL CHECK (LowPercentage > 0), HighPercentage NUMERIC(5,2) NOT NULL CHECK (HighPercentage > 0), PRIMARY KEY(Section, LetterGrade), @@ -132,7 +132,7 @@ CREATE TABLE Gradebook.Section_GradeTier ); -CREATE TABLE Gradebook.Student +CREATE TABLE Student ( ID SERIAL PRIMARY KEY, FName VARCHAR(50), --at least one of the name fields must be used: see below @@ -148,13 +148,13 @@ CREATE TABLE Gradebook.Student --enforce case-insensitive uniqueness of student e-mail addresses CREATE UNIQUE INDEX idx_Unique_StudentEmail -ON Gradebook.Student(LOWER(TRIM(Email))); +ON Student(LOWER(TRIM(Email))); -CREATE TABLE Gradebook.Enrollee +CREATE TABLE Enrollee ( - Student INT NOT NULL REFERENCES Gradebook.Student, - Section INT REFERENCES Gradebook.Section, + Student INT NOT NULL REFERENCES Student, + Section INT REFERENCES Section, DateEnrolled DATE NULL, --used to figure out which assessment components to include/exclude YearEnrolled VARCHAR(30) NOT NULL, MajorEnrolled VARCHAR(50) NOT NULL, @@ -165,32 +165,32 @@ CREATE TABLE Gradebook.Enrollee FinalGradeComputed VARCHAR(2), --will eventually move to a view FinalGradeAwarded VARCHAR(2), --actual grade assigned PRIMARY KEY (Student, Section), - FOREIGN KEY (Section, MidtermGradeAwarded) REFERENCES Gradebook.Section_GradeTier, - FOREIGN KEY (Section, FinalGradeAwarded) REFERENCES Gradebook.Section_GradeTier + FOREIGN KEY (Section, MidtermGradeAwarded) REFERENCES Section_GradeTier, + FOREIGN KEY (Section, FinalGradeAwarded) REFERENCES Section_GradeTier ); -CREATE TABLE Gradebook.AttendanceStatus +CREATE TABLE AttendanceStatus ( Status CHAR(1) NOT NULL PRIMARY KEY, --'P', 'A', ... Description VARCHAR(20) NOT NULL UNIQUE --'Present', 'Absent', ... ); -CREATE TABLE Gradebook.AttendanceRecord +CREATE TABLE AttendanceRecord ( Student INT NOT NULL, Section INT NOT NULL, Date DATE NOT NULL, - Status CHAR(1) NOT NULL REFERENCES Gradebook.AttendanceStatus, + Status CHAR(1) NOT NULL REFERENCES AttendanceStatus, PRIMARY KEY (Student, Section, Date), - FOREIGN KEY (Student, Section) REFERENCES Gradebook.Enrollee + FOREIGN KEY (Student, Section) REFERENCES Enrollee ); -CREATE TABLE Gradebook.Section_AssessmentComponent +CREATE TABLE Section_AssessmentComponent ( - Section INT NOT NULL REFERENCES Gradebook.Section, + Section INT NOT NULL REFERENCES Section, Type VARCHAR(20) NOT NULL, --"Assignment", "Quiz", "Exam",... Weight NUMERIC(3,2) NOT NULL CHECK (Weight >= 0), --a percentage value: 0.25, 0.5,... NumItems INT NOT NULL DEFAULT 1, @@ -198,7 +198,7 @@ CREATE TABLE Gradebook.Section_AssessmentComponent ); -CREATE TABLE Gradebook.Section_AssessmentItem +CREATE TABLE Section_AssessmentItem ( Section INT NOT NULL, Component VARCHAR(20) NOT NULL, @@ -208,11 +208,11 @@ CREATE TABLE Gradebook.Section_AssessmentItem AssignedDate Date, DueDate Date, PRIMARY KEY(Section, Component, SequenceInComponent), - FOREIGN KEY (Section, Component) REFERENCES Gradebook.Section_AssessmentComponent + FOREIGN KEY (Section, Component) REFERENCES Section_AssessmentComponent ); -CREATE TABLE Gradebook.Enrollee_AssessmentItem +CREATE TABLE Enrollee_AssessmentItem ( Student INT NOT NULL, Section INT NOT NULL, @@ -223,6 +223,6 @@ CREATE TABLE Gradebook.Enrollee_AssessmentItem SubmissionDate DATE, Penalty NUMERIC(5,2) CHECK (Penalty >= 0), PRIMARY KEY(Student, Section, Component, SequenceInComponent), - FOREIGN KEY (Student, Section) REFERENCES Gradebook.Enrollee, - FOREIGN KEY (Section, Component, SequenceInComponent) REFERENCES Gradebook.Section_AssessmentItem + FOREIGN KEY (Student, Section) REFERENCES Enrollee, + FOREIGN KEY (Section, Component, SequenceInComponent) REFERENCES Section_AssessmentItem ); diff --git a/src/db/dropTables.sql b/src/db/dropTables.sql index c70c2b2..217ec8f 100644 --- a/src/db/dropTables.sql +++ b/src/db/dropTables.sql @@ -16,10 +16,6 @@ START TRANSACTION; ---Remove the following line to drop tables from default schema instead -SET LOCAL SCHEMA 'gradebook'; - - DROP TABLE IF EXISTS Course CASCADE; DROP TABLE IF EXISTS Season CASCADE; DROP TABLE IF EXISTS Term CASCADE; diff --git a/src/db/humanizeStudentData.sql b/src/db/humanizeStudentData.sql index c871271..dac6303 100644 --- a/src/db/humanizeStudentData.sql +++ b/src/db/humanizeStudentData.sql @@ -235,7 +235,7 @@ BEGIN -- test a concatenation of all name columns to prevent falsely identifying -- a row as needing update: unlikely a real human name has all name parts -- made of only hex digits. "Ada E Cadefa"? "Abe Bead"? - UPDATE Gradebook.Student + UPDATE Student SET FName = pg_temp.GetHumanNamePart(FName, '0', numOfFirstNames), MName = pg_temp.GetHumanNamePart(MName, '1', numOfMiddleNames), LName = pg_temp.GetHumanNamePart(LName, '2', numOfLastNames) diff --git a/src/db/importCourseSchedule/README.md b/src/db/importCourseSchedule/README.md index af6dbcc..24ea39d 100644 --- a/src/db/importCourseSchedule/README.md +++ b/src/db/importCourseSchedule/README.md @@ -58,7 +58,17 @@ tables `Gradebook.Term`, `Gradebook.Course`, `Gradebook.Section`, and The import procedure implemented can be executed on a Microsoft Windows system by running the batch command `importCourseScheduleCSV.bat`. This command accepts -a few parameters and uses the `psql` client to run all three steps of the import procedure: +a few parameters and uses the `psql` client to run all three steps of the import procedure. + +Before running the batch file, the following command may need to be executed in psql to ensure that the +installation takes affect in the correct database and the correct schema(s): + +`ALTER ROLE role IN DATABASE database SET search_path TO schema1, schema2, pg_temp;` + +Notes concerning the command above: +* `role` and `database` are the user's target role and database, respectively +* `IN DATABASE database` is optional, but not specifying a target database will make the change to all databases +* One or more schemas may take the place of `schema1, schema2', however 'pg_temp' must always remain at the end of the list. To execute the procedure, open a Command window and run the batch command as shown below. The strings shown after the command name are parameters; strings diff --git a/src/db/importCourseSchedule/prepareCourseScheduleImport.sql b/src/db/importCourseSchedule/prepareCourseScheduleImport.sql index bca7e99..89a6a16 100644 --- a/src/db/importCourseSchedule/prepareCourseScheduleImport.sql +++ b/src/db/importCourseSchedule/prepareCourseScheduleImport.sql @@ -54,18 +54,18 @@ $$ WITH LatestYear AS ( SELECT Year, Season - FROM Gradebook.Term - WHERE Year = (SELECT MAX(Year) FROM Gradebook.Term) + FROM Term + WHERE Year = (SELECT MAX(Year) FROM Term) ) SELECT CASE --Check for the case when there are no terms, as we can't check --the sequence if it hasn't been started yet - WHEN (SELECT COUNT(*) FROM Gradebook.Term) > 0 THEN + WHEN (SELECT COUNT(*) FROM Term) > 0 THEN ( - MAX(LY.Year) * (SELECT COUNT(*) FROM Gradebook.Season) + + MAX(LY.Year) * (SELECT COUNT(*) FROM Season) + MAX(LY.Season) + 1 ) = ( - $1 * (SELECT COUNT(*) FROM Gradebook.Season) + $2 + $1 * (SELECT COUNT(*) FROM Season) + $2 ) ELSE TRUE @@ -90,7 +90,7 @@ DECLARE BEGIN --Get the season order from the provided 'season identification' --This can be either a code, order, or name - SELECT Gradebook.getSeasonOrder($2) + SELECT getSeasonOrder($2) INTO seasonOrder; --Check if the provided term is the next term chronologically after the last imported @@ -110,7 +110,7 @@ BEGIN FROM pg_temp.CourseScheduleStaging ) --Select the extreme start and end dates from TermDates - INSERT INTO Gradebook.Term(Year, Season, StartDate, EndDate) + INSERT INTO Term(Year, Season, StartDate, EndDate) SELECT $1, seasonOrder, $1 + MIN(to_date(sDate, 'MM-DD')), $1 + MAX(to_date(eDate, 'MM-DD')) @@ -118,7 +118,7 @@ BEGIN ON CONFLICT DO NOTHING; --Insert course into Course, concat subject || course to make 'Number' - INSERT INTO Gradebook.Course(Number, Title) + INSERT INTO Course(Number, Title) SELECT DISTINCT ON (n) (Subject || Course) n, Title FROM pg_temp.CourseScheduleStaging WHERE NOT Subject IS NULL @@ -127,8 +127,8 @@ BEGIN DO UPDATE SET Title = EXCLUDED.Title; - --The first CTE inserts new instructors into Gradebook.Instructor, and RETURNS - -- their full names for insertion into Gradebook.Section table + --The first CTE inserts new instructors into Instructor, and RETURNS + -- their full names for insertion into Section table WITH insertedFullNames AS ( --This CTE creates a table of individual instructor names from single section, @@ -154,7 +154,7 @@ BEGIN -- This method also ignores "names" like 'TBA' WHERE instructor LIKE '% %' ) - INSERT INTO Gradebook.Instructor (FName, MName, LName) + INSERT INTO Instructor (FName, MName, LName) --Select the name parts from the array into the new Instructor row --EX. Name[1] = FName SELECT Name[1], @@ -171,15 +171,15 @@ BEGIN RETURNING id, FName || ' ' || COALESCE(MName || ' ', '') || LName as FullName ), --This second CTE UNIONS any existing instructors that were not inserted into - -- Gradebook.Instructor so they can be used for insertion into Gradebook.Section + -- Instructor so they can be used for insertion into Section instructorFullNames AS ( SELECT id, FullName FROM insertedFullNames UNION SELECT id, FName || ' ' || COALESCE(MName || ' ', '') || LName as FullName - FROM Gradebook.Instructor + FROM Instructor ) - INSERT INTO Gradebook.Section(CRN, Course, SectionNumber, Term, Schedule, + INSERT INTO Section(CRN, Course, SectionNumber, Term, Schedule, StartDate, EndDate, Location, Instructor1, Instructor2, Instructor3) SELECT oc.CRN, oc.Subject || oc.Course, oc.Section, t.ID, oc.Days, @@ -188,7 +188,7 @@ BEGIN to_date($1 || '/' || (string_to_array(Date, '-'))[2], 'YYYY/MM/DD'), oc.Location, i1.ID, i2.ID, i3.ID FROM pg_temp.CourseScheduleStaging oc - JOIN Gradebook.Term t ON t.Year = $1 + JOIN Term t ON t.Year = $1 AND t.Season = seasonOrder --These joins get the instructor ID for up to three instructors teaching a section JOIN instructorFullNames i1 ON diff --git a/src/db/importRoster/README.md b/src/db/importRoster/README.md index ec7a882..41332ed 100644 --- a/src/db/importRoster/README.md +++ b/src/db/importRoster/README.md @@ -60,7 +60,17 @@ tables `Gradebook.Student` and `Gradebook.Enrollee`. The import procedure implemented can be executed on a Microsoft Windows system by running the batch command `importRosterCSV.bat`. This command accepts -a few parameters and uses the `psql` client to run all three steps of the import procedure: +a few parameters and uses the `psql` client to run all three steps of the import procedure. + +Before running the batch file, the following command may need to be executed in psql to ensure that the +installation takes affect in the correct database and the correct schema(s): + +`ALTER ROLE role IN DATABASE database SET search_path TO schema1, schema2, pg_temp;` + +Notes concerning the command above: +* `role` and `database` are the user's target role and database, respectively +* `IN DATABASE database` is optional, but not specifying a target database will make the change to all databases +* One or more schemas may take the place of `schema1, schema2', however 'pg_temp' must always remain at the end of the list. To execute the procedure, open a Command window and run the batch command as shown below. The strings shown after the command name are parameters; strings diff --git a/src/db/importRoster/prepareRosterImport.sql b/src/db/importRoster/prepareRosterImport.sql index c50e2c6..b6d2aaf 100644 --- a/src/db/importRoster/prepareRosterImport.sql +++ b/src/db/importRoster/prepareRosterImport.sql @@ -39,7 +39,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS RosterStaging --Function to import a roster currently in the rosterStaging table --param seasonIdentification is a season order, code, or name --- see function Gradebook.getSeasonOrder(VARCHAR(20)) +-- see function getSeasonOrder(VARCHAR(20)) CREATE OR REPLACE FUNCTION pg_temp.importRoster(year INT, seasonIdentification VARCHAR(20), course VARCHAR(8), @@ -52,7 +52,7 @@ $$ --add students: if a student already exists, update selected fields -- assumes rosters are imported in chronological order so that updating -- info of an existing student reflects the most recent info for that student - INSERT INTO Gradebook.Student(FName, MName, LName, SchoolIssuedID, Email, + INSERT INTO Student(FName, MName, LName, SchoolIssuedID, Email, Major, Year ) SELECT r.FName, r.MName, r.LName, r.ID, r.email, r.Major, r.Class @@ -70,16 +70,16 @@ $$ WITH FixedEnrollmentInfo(SectionID, StartDate) AS ( SELECT ID, (CASE WHEN $5 > N.StartDate THEN $5 ELSE NULL END) - FROM Gradebook.getSection($1, $2, $3, $4) N + FROM getSection($1, $2, $3, $4) N ) --record students as enrollees in the section: ignore conflicts - INSERT INTO Gradebook.Enrollee(Student, Section, DateEnrolled, YearEnrolled, + INSERT INTO Enrollee(Student, Section, DateEnrolled, YearEnrolled, MajorEnrolled ) SELECT S.ID, f.SectionID, f.StartDate, r.Class, r.Major FROM FixedEnrollmentInfo f, pg_temp.RosterStaging r - JOIN Gradebook.Student S ON r.ID = S.SchoolIssuedID + JOIN Student S ON r.ID = S.SchoolIssuedID ON CONFLICT DO NOTHING; $$ LANGUAGE SQL; diff --git a/src/db/initializeDB.sql b/src/db/initializeDB.sql index 5af70f4..93e3c94 100644 --- a/src/db/initializeDB.sql +++ b/src/db/initializeDB.sql @@ -113,14 +113,12 @@ REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC; GRANT ALL PRIVILEGES ON SCHEMA public TO Gradebook; ---Create a schema to hold app-specific info and permit only the Gradebook role ---to create or use objects in that schema --- this code might have to be moved to a function if schemas are used to support --- multi-tenancy (schema name will be a parameter) -CREATE SCHEMA IF NOT EXISTS Gradebook; -REVOKE ALL PRIVILEGES ON SCHEMA Gradebook FROM PUBLIC; -GRANT ALL PRIVILEGES ON SCHEMA Gradebook TO Gradebook; - +--Permit only the Gradebook role to create or use objects in the +-- current schema. This code might have to be moved to a function if +-- schemas are used to support multi-tenancy (schema name will +-- be a parameter) +REVOKE ALL PRIVILEGES ON SCHEMA CURRENT_SCHEMA FROM PUBLIC; +GRANT ALL PRIVILEGES ON SCHEMA CURRENT_SCHEMA TO Gradebook; COMMIT; diff --git a/src/webapp/gradebookServer.js b/src/webapp/gradebookServer.js index 29f1366..3815a0d 100644 --- a/src/webapp/gradebookServer.js +++ b/src/webapp/gradebookServer.js @@ -132,7 +132,7 @@ app.get('/login', function(request, response) { var instructorEmail = request.query.instructoremail.trim(); //Set the query text - var queryText = 'SELECT ID, FName, MName, LName, Department FROM gradebook.getInstructor($1);'; + var queryText = 'SELECT ID, FName, MName, LName, Department FROM getInstructor($1);'; var queryParams = [instructorEmail]; //Execute the query @@ -165,7 +165,7 @@ app.get('/years', function(request, response) { var instructorID = request.query.instructorid; //Set the query text - var queryText = 'SELECT Year FROM gradebook.getInstructorYears($1);'; + var queryText = 'SELECT Year FROM getInstructorYears($1);'; var queryParams = [instructorID]; //Execute the query @@ -196,7 +196,7 @@ app.get('/seasons', function(request, response) { var year = request.query.year; //Set the query text - var queryText = 'SELECT SeasonOrder, SeasonName FROM gradebook.getInstructorSeasons($1, $2);'; + var queryText = 'SELECT SeasonOrder, SeasonName FROM getInstructorSeasons($1, $2);'; var queryParams = [instructorID, year]; //Execute the query @@ -231,7 +231,7 @@ app.get('/courses', function(request, response) { var year = request.query.year; var seasonOrder = request.query.seasonorder; - var queryText = 'SELECT Course FROM gradebook.getInstructorCourses($1, $2, $3);'; + var queryText = 'SELECT Course FROM getInstructorCourses($1, $2, $3);'; var queryParams = [instructorID, year, seasonOrder]; executeQuery(response, config, queryText, queryParams, function(result) { @@ -262,7 +262,7 @@ app.get('/sections', function(request, response) { var seasonOrder = request.query.seasonorder; var courseNumber = request.query.coursenumber; - var queryText = 'SELECT SectionID, SectionNumber FROM gradebook.getInstructorSections($1, $2, $3, $4);'; + var queryText = 'SELECT SectionID, SectionNumber FROM getInstructorSections($1, $2, $3, $4);'; var queryParams = [instructorID, year, seasonOrder, courseNumber]; executeQuery(response, config, queryText, queryParams, function(result) { @@ -296,11 +296,11 @@ app.get('/attendance', function(request, response) { var sectionID = request.query.sectionid; //Set the query text and package the parameters in an array - var queryText = 'SELECT AttendanceCSVWithHeader FROM gradebook.getAttendance($1);'; + var queryText = 'SELECT AttendanceCSVWithHeader FROM getAttendance($1);'; var queryParams = [sectionID]; //Setup the second query, to get the attendance code description table - var queryTextAttnDesc = 'SELECT Status, Description FROM gradebook.AttendanceStatus'; + var queryTextAttnDesc = 'SELECT Status, Description FROM AttendanceStatus'; //Execute the attendance description query first //attnStatusRes will hold the table containg the code descriptions diff --git a/tests/data/Attendance/importAttendance.psql b/tests/data/Attendance/importAttendance.psql index 1ff27c6..1b42842 100644 --- a/tests/data/Attendance/importAttendance.psql +++ b/tests/data/Attendance/importAttendance.psql @@ -46,7 +46,7 @@ $$ --Add AttendanceStaging.Code values that do not exist in AttendanceStatus. -- Code is also used as both the Status and Description attributes if an INSERT -- is performed. Does not ignore conflicts on AttendanceStatus.Description. - INSERT INTO Gradebook.AttendanceStatus + INSERT INTO AttendanceStatus SELECT DISTINCT UPPER(Code), UPPER(Code) FROM pg_temp.AttendanceStaging WHERE Code IS NOT NULL @@ -55,10 +55,10 @@ $$ --Match student from each entry in sample data with their corresponsing entry in -- the Student table by joining on a match of the 3 name parts. MName can be NULL -- and rows with NULL as the attendance code are interpreted as Present and not - -- imported. (See behavior of Gradebook.getAttendance() in /src/db/getAttendance.sql) - INSERT INTO Gradebook.AttendanceRecord + -- imported. (See behavior of getAttendance() in /src/db/getAttendance.sql) + INSERT INTO AttendanceRecord SELECT s.ID, $1, a.Date, UPPER(a.Code) - FROM pg_temp.AttendanceStaging a JOIN Gradebook.Student s ON + FROM pg_temp.AttendanceStaging a JOIN Student s ON a.FName = s.FName AND a.LName = s.LName AND COALESCE(a.MName, '') = COALESCE(s.MName, '') WHERE a.Code IS NOT NULL @@ -69,13 +69,13 @@ $$ LANGUAGE sql --Import data from files to staging table and call import function for each section \COPY pg_temp.AttendanceStaging FROM '2017SpringCS110-05Attendance.csv' WITH csv HEADER -SELECT pg_temp.importAttendance(Gradebook.getSectionID(2017, 0, 'CS110', '5')); +SELECT pg_temp.importAttendance(getSectionID(2017, 0, 'CS110', '5')); TRUNCATE pg_temp.AttendanceStaging; \COPY pg_temp.AttendanceStaging FROM '2017SpringCS110-72Attendance.csv' WITH csv HEADER -SELECT pg_temp.importAttendance(Gradebook.getSectionID(2017, 0, 'CS110', '72')); +SELECT pg_temp.importAttendance(getSectionID(2017, 0, 'CS110', '72')); TRUNCATE pg_temp.AttendanceStaging; \COPY pg_temp.AttendanceStaging FROM '2017SpringCS110-74Attendance.csv' WITH csv HEADER -SELECT pg_temp.importAttendance(Gradebook.getSectionID(2017, 0, 'CS110', '74')); +SELECT pg_temp.importAttendance(getSectionID(2017, 0, 'CS110', '74')); TRUNCATE pg_temp.AttendanceStaging; diff --git a/tests/data/InstructorEmail/addEmailByInstructorID.sql b/tests/data/InstructorEmail/addEmailByInstructorID.sql index 11da057..5a74831 100644 --- a/tests/data/InstructorEmail/addEmailByInstructorID.sql +++ b/tests/data/InstructorEmail/addEmailByInstructorID.sql @@ -43,13 +43,13 @@ ON pg_temp.Instructor(LOWER(TRIM(Email))); --try assigning ID INSERT INTO pg_temp.Instructor SELECT ID, CONCAT(ID, '@example.edu') -FROM Gradebook.Instructor +FROM Instructor WHERE Email IS NULL ON CONFLICT DO NOTHING; --transfer e-mail addresses from the temporary table to Gradebook -UPDATE Gradebook.Instructor I1 +UPDATE Instructor I1 SET Email = I2.Email FROM pg_temp.Instructor I2 WHERE I1.Email IS NULL AND I1.ID = I2.ID; diff --git a/tests/data/InstructorEmail/addEmailByInstructorName.sql b/tests/data/InstructorEmail/addEmailByInstructorName.sql index 2855dec..4a3928a 100644 --- a/tests/data/InstructorEmail/addEmailByInstructorName.sql +++ b/tests/data/InstructorEmail/addEmailByInstructorName.sql @@ -45,14 +45,14 @@ ON pg_temp.Instructor(LOWER(TRIM(Email))); -- need to do this so existing addresses are not reused INSERT INTO pg_temp.Instructor SELECT ID, Email -FROM Gradebook.Instructor +FROM Instructor WHERE Email LIKE '%@example.edu'; --try assigning last name and first initial for instructors with no middle name INSERT INTO pg_temp.Instructor SELECT ID, CONCAT(LName, LEFT(FName, 1), '@example.edu') -FROM Gradebook.Instructor +FROM Instructor WHERE Email IS NULL AND COALESCE(MName, '') = '' ON CONFLICT DO NOTHING; @@ -60,7 +60,7 @@ ON CONFLICT DO NOTHING; --try assigning last name and first initial INSERT INTO pg_temp.Instructor SELECT ID, CONCAT(LName, LEFT(FName, 1), '@example.edu') -FROM Gradebook.Instructor +FROM Instructor WHERE Email IS NULL AND ID NOT IN (SELECT ID FROM pg_temp.Instructor) ON CONFLICT DO NOTHING; @@ -68,7 +68,7 @@ ON CONFLICT DO NOTHING; --try assigning last name, first initial, middle initial INSERT INTO pg_temp.Instructor SELECT ID, CONCAT(LName, LEFT(FName, 1), LEFT(MName, 1), '@example.edu') -FROM Gradebook.Instructor +FROM Instructor WHERE Email IS NULL AND ID NOT IN (SELECT ID FROM pg_temp.Instructor) ON CONFLICT DO NOTHING; @@ -76,7 +76,7 @@ ON CONFLICT DO NOTHING; --try assigning last name, first initial, 2 letters of middle name INSERT INTO pg_temp.Instructor SELECT ID, CONCAT(LName, LEFT(FName, 1), LEFT(MName, 2), '@example.edu') -FROM Gradebook.Instructor +FROM Instructor WHERE Email IS NULL AND ID NOT IN (SELECT ID FROM pg_temp.Instructor) ON CONFLICT DO NOTHING; @@ -84,13 +84,13 @@ ON CONFLICT DO NOTHING; --try assigning last name, first initial, ID INSERT INTO pg_temp.Instructor SELECT ID, CONCAT(LName, LEFT(FName, 1), ID, '@example.edu') -FROM Gradebook.Instructor +FROM Instructor WHERE Email IS NULL AND ID NOT IN (SELECT ID FROM pg_temp.Instructor) ON CONFLICT DO NOTHING; --transfer e-mail addresses from the temporary table to Gradebook -UPDATE Gradebook.Instructor I1 +UPDATE Instructor I1 SET Email = I2.Email FROM pg_temp.Instructor I2 WHERE I1.Email IS NULL AND I1.ID = I2.ID; diff --git a/tests/humanizeStudentData/addTestData.sql b/tests/humanizeStudentData/addTestData.sql index ff679f8..52753ae 100644 --- a/tests/humanizeStudentData/addTestData.sql +++ b/tests/humanizeStudentData/addTestData.sql @@ -31,7 +31,7 @@ actual email address */ -INSERT INTO Gradebook.Student(FName, MName, LName, SchoolIssuedID, Email) +INSERT INTO Student(FName, MName, LName, SchoolIssuedID, Email) VALUES --rows that should be altered by humanization diff --git a/tests/humanizeStudentData/testResults.sql b/tests/humanizeStudentData/testResults.sql index b9c322e..220d26b 100644 --- a/tests/humanizeStudentData/testResults.sql +++ b/tests/humanizeStudentData/testResults.sql @@ -32,7 +32,7 @@ BEGIN RAISE INFO '% Row count', (SELECT - CASE (SELECT COUNT(*) FROM Gradebook.Student + CASE (SELECT COUNT(*) FROM Student WHERE Email ~ '[1-8]@example\.com' ) WHEN 8 THEN 'PASS' @@ -49,7 +49,7 @@ BEGIN WHEN true THEN 'FAIL: Code 1' ELSE 'PASS' END - FROM Gradebook.Student + FROM Student WHERE Email = '1@example.com' ); @@ -60,7 +60,7 @@ BEGIN WHEN true THEN 'FAIL: Code 2' ELSE 'PASS' END - FROM Gradebook.Student + FROM Student WHERE Email = '2@example.com' ); @@ -71,7 +71,7 @@ BEGIN WHEN true THEN 'FAIL: Code 3' ELSE 'PASS' END - FROM Gradebook.Student + FROM Student WHERE Email = '3@example.com' ); @@ -82,7 +82,7 @@ BEGIN WHEN true THEN 'FAIL: Code 4' ELSE 'PASS' END - FROM Gradebook.Student + FROM Student WHERE Email = '4@example.com' ); @@ -93,7 +93,7 @@ BEGIN WHEN true THEN 'FAIL: Code 5' ELSE 'PASS' END - FROM Gradebook.Student + FROM Student WHERE Email = '5@example.com' ); @@ -104,7 +104,7 @@ BEGIN WHEN true THEN 'FAIL: Code 6' ELSE 'PASS' END - FROM Gradebook.Student + FROM Student WHERE Email = '6@example.com' ); @@ -117,7 +117,7 @@ BEGIN WHEN true THEN 'FAIL: Code 7' ELSE 'PASS' END - FROM Gradebook.Student + FROM Student WHERE Email = '7@example.com' ); @@ -128,13 +128,13 @@ BEGIN WHEN true THEN 'FAIL: Code 8' ELSE 'PASS' END - FROM Gradebook.Student + FROM Student WHERE Email = '8@example.com' ); --remove test rows - DELETE FROM Gradebook.Student + DELETE FROM Student WHERE Email ~ '[1-8]@example\.com'; END diff --git a/tests/testInstructorMgmt.sql b/tests/testInstructorMgmt.sql index 8bafc61..8c31418 100644 --- a/tests/testInstructorMgmt.sql +++ b/tests/testInstructorMgmt.sql @@ -31,32 +31,32 @@ BEGIN --Step 1: add test data --add two courses - INSERT INTO Gradebook.Course + INSERT INTO Course VALUES ('AB101', 'Course AB 101'), ('CD201', 'Course CD 201') ON CONFLICT DO NOTHING; --add two seasons - INSERT INTO Gradebook.Season + INSERT INTO Season VALUES (0, 'Spring', 'S'), (1, 'Summer', 'M') ON CONFLICT DO NOTHING; --add two terms: 2017 Spring, 2017 Summer - INSERT INTO Gradebook.Term(Year, Season, StartDate, EndDate) + INSERT INTO Term(Year, Season, StartDate, EndDate) VALUES (2017, 0, current_date, current_date+1), (2017, 1, current_date, current_date+1) ON CONFLICT DO NOTHING; --extract the IDs assigned to the two terms just added - SELECT ID FROM Gradebook.Term + SELECT ID FROM Term WHERE Year = 2017 AND Season = 0 INTO term2017Spring; - SELECT ID FROM Gradebook.Term + SELECT ID FROM Term WHERE Year = 2017 AND Season = 1 INTO term2017Summer; @@ -65,17 +65,17 @@ BEGIN --however, because some tests are count-based, do not ignore conflicts as is --done with other tables; instead let the transaction fail so the test is --abandoned - INSERT INTO Gradebook.Instructor(FName, LName, Email) + INSERT INTO Instructor(FName, LName, Email) VALUES ('F1', 'L1', 'f1.l1@example.com'), ('F2', 'L2', 'f2.l2@example.com'); --extract IDs of the two instructors - SELECT ID FROM Gradebook.Instructor + SELECT ID FROM Instructor WHERE Email = 'f1.l1@example.com' INTO instructor1; - SELECT ID FROM Gradebook.Instructor + SELECT ID FROM Instructor WHERE Email = 'f2.l2@example.com' INTO instructor2; @@ -84,7 +84,7 @@ BEGIN --i1 and i2 each teach their own section as well --i1 teaches two sections in just one term: 2017 Spring --i2 teaches one section in 2017 Spring; one in 2017 Summer - INSERT INTO Gradebook.Section(Term, Course, SectionNumber, CRN, + INSERT INTO Section(Term, Course, SectionNumber, CRN, Instructor1, Instructor2 ) VALUES @@ -99,9 +99,9 @@ BEGIN --test if getInstructors returns same #rows as directly obtained from table RAISE INFO '% getInstructors Count', (SELECT - CASE ((SELECT COUNT(*) FROM Gradebook.getInstructors()) + CASE ((SELECT COUNT(*) FROM getInstructors()) = - (SELECT COUNT(*) FROM Gradebook.Instructor) + (SELECT COUNT(*) FROM Instructor) ) WHEN true THEN 'PASS' ELSE 'FAIL: Code 1' @@ -112,7 +112,7 @@ BEGIN --test if getInstructor finds instructor1 by e-mail address RAISE INFO '% getInstructor(email) Count', (SELECT - CASE (SELECT COUNT(*) FROM Gradebook.getInstructor('f1.l1@example.com')) + CASE (SELECT COUNT(*) FROM getInstructor('f1.l1@example.com')) WHEN 1 THEN 'PASS' ELSE 'FAIL: Code 2' END @@ -123,7 +123,7 @@ BEGIN --an invalid email address is used to simulate look-up falure RAISE INFO '% getInstructor(emai) Count Negative', (SELECT - CASE (SELECT COUNT(*) FROM Gradebook.getInstructor('not_a_mail_address')) + CASE (SELECT COUNT(*) FROM getInstructor('not_a_mail_address')) WHEN 0 THEN 'PASS' ELSE 'FAIL: Code 3' END @@ -133,7 +133,7 @@ BEGIN --test if getInstructor returns F1 as first name of instructor1 RAISE INFO '% getInstructor(instructorID) Value', (SELECT - CASE (SELECT FName FROM Gradebook.getInstructor(instructor1) LIMIT 1) + CASE (SELECT FName FROM getInstructor(instructor1) LIMIT 1) WHEN 'F1' THEN 'PASS' ELSE 'FAIL: Code 4' END @@ -143,7 +143,7 @@ BEGIN --test if getInstructorYears returns one row for instructor1 RAISE INFO '% getInstructorYears Count', (SELECT - CASE (SELECT COUNT(*) FROM Gradebook.getInstructorYears(instructor1)) + CASE (SELECT COUNT(*) FROM getInstructorYears(instructor1)) WHEN 1 THEN 'PASS' ELSE 'FAIL: Code 5' END @@ -153,7 +153,7 @@ BEGIN --test if getInstructorYears returns 2017 for instructor1 RAISE INFO '% getInstructorYears Value', (SELECT - CASE (SELECT Year FROM Gradebook.getInstructorYears(instructor1) LIMIT 1) + CASE (SELECT Year FROM getInstructorYears(instructor1) LIMIT 1) WHEN 2017 THEN 'PASS' ELSE 'FAIL: Code 6' END @@ -164,7 +164,7 @@ BEGIN RAISE INFO '% getInstructorSeasons(instructor1) Count', (SELECT CASE (SELECT COUNT(*) - FROM Gradebook.getInstructorSeasons(instructor1, 2017) + FROM getInstructorSeasons(instructor1, 2017) ) WHEN 1 THEN 'PASS' ELSE 'FAIL: Code 7' @@ -176,7 +176,7 @@ BEGIN RAISE INFO '% getInstructorSeasons(instructor1) Value', (SELECT CASE (SELECT SeasonName - FROM Gradebook.getInstructorSeasons(instructor1, 2017) + FROM getInstructorSeasons(instructor1, 2017) LIMIT 1 ) WHEN 'Spring' THEN 'PASS' @@ -189,7 +189,7 @@ BEGIN RAISE INFO '% getInstructorSeasons(instructor2) Count', (SELECT CASE (SELECT COUNT(*) - FROM Gradebook.getInstructorSeasons(instructor2, 2017) + FROM getInstructorSeasons(instructor2, 2017) ) WHEN 2 THEN 'PASS' ELSE 'FAIL: Code 9' @@ -201,7 +201,7 @@ BEGIN RAISE INFO '% getInstructorCourses(instructor1) Count', (SELECT CASE (SELECT COUNT(*) - FROM Gradebook.getInstructorCourses(instructor1, 2017, 0) + FROM getInstructorCourses(instructor1, 2017, 0) ) WHEN 2 THEN 'PASS' ELSE 'FAIL: Code 10' @@ -213,7 +213,7 @@ BEGIN RAISE INFO '% getInstructorCourses(instructor2) Count', (SELECT CASE (SELECT COUNT(*) - FROM Gradebook.getInstructorCourses(instructor2, 2017, 1) + FROM getInstructorCourses(instructor2, 2017, 1) ) WHEN 1 THEN 'PASS' ELSE 'FAIL: Code 11' @@ -225,7 +225,7 @@ BEGIN RAISE INFO '% getInstructorCourses(instructor2) Value', (SELECT CASE (SELECT Course - FROM Gradebook.getInstructorCourses(instructor2, 2017, 1) + FROM getInstructorCourses(instructor2, 2017, 1) LIMIT 1 ) WHEN 'AB101' THEN 'PASS' @@ -238,7 +238,7 @@ BEGIN RAISE INFO '% getInstructorCourses(instructor1) Count Negative', (SELECT CASE (SELECT COUNT(*) - FROM Gradebook.getInstructorCourses(instructor1, 2017, 1) + FROM getInstructorCourses(instructor1, 2017, 1) ) WHEN 0 THEN 'PASS' ELSE 'FAIL: Code 13' @@ -250,7 +250,7 @@ BEGIN RAISE INFO '% getInstructorSections(instructor1) Count', (SELECT CASE (SELECT COUNT(*) - FROM Gradebook.getInstructorSections(instructor1, 2017, 0) + FROM getInstructorSections(instructor1, 2017, 0) ) WHEN 2 THEN 'PASS' ELSE 'FAIL: Code 14' @@ -262,7 +262,7 @@ BEGIN RAISE INFO '% getInstructorSections(instructor2) Value', (SELECT CASE (SELECT SectionNumber - FROM Gradebook.getInstructorSections(instructor2, 2017, 1, 'AB101') + FROM getInstructorSections(instructor2, 2017, 1, 'AB101') LIMIT 1 ) WHEN '02' THEN 'PASS'