mirror of
https://github.com/Xevion/banner.git
synced 2025-12-08 04:06:29 -06:00
feat: setup diesel & schema, course with metrics/audit tables
This commit is contained in:
9
diesel.toml
Normal file
9
diesel.toml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# For documentation on how to configure this file,
|
||||||
|
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
|
[print_schema]
|
||||||
|
file = "src/data/schema.rs"
|
||||||
|
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||||
|
|
||||||
|
[migrations_directory]
|
||||||
|
dir = "migrations"
|
||||||
0
migrations/.keep
Normal file
0
migrations/.keep
Normal file
6
migrations/00000000000000_diesel_initial_setup/down.sql
Normal file
6
migrations/00000000000000_diesel_initial_setup/down.sql
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
-- This file was automatically created by Diesel to setup helper functions
|
||||||
|
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||||
|
-- changes will be added to existing projects as new migrations.
|
||||||
|
|
||||||
|
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
||||||
|
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
||||||
36
migrations/00000000000000_diesel_initial_setup/up.sql
Normal file
36
migrations/00000000000000_diesel_initial_setup/up.sql
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
-- This file was automatically created by Diesel to setup helper functions
|
||||||
|
-- and other internal bookkeeping. This file is safe to edit, any future
|
||||||
|
-- changes will be added to existing projects as new migrations.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Sets up a trigger for the given table to automatically set a column called
|
||||||
|
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
||||||
|
-- in the modified columns)
|
||||||
|
--
|
||||||
|
-- # Example
|
||||||
|
--
|
||||||
|
-- ```sql
|
||||||
|
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
||||||
|
--
|
||||||
|
-- SELECT diesel_manage_updated_at('users');
|
||||||
|
-- ```
|
||||||
|
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
||||||
|
BEGIN
|
||||||
|
IF (
|
||||||
|
NEW IS DISTINCT FROM OLD AND
|
||||||
|
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
||||||
|
) THEN
|
||||||
|
NEW.updated_at := current_timestamp;
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
4
migrations/2025-08-27-231618_setup/down.sql
Normal file
4
migrations/2025-08-27-231618_setup/down.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE IF EXISTS "courses";
|
||||||
|
DROP TABLE IF EXISTS "course_metrics";
|
||||||
|
DROP TABLE IF EXISTS "course_audits";
|
||||||
35
migrations/2025-08-27-231618_setup/up.sql
Normal file
35
migrations/2025-08-27-231618_setup/up.sql
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
CREATE TABLE "courses"(
|
||||||
|
"id" INT4 NOT NULL PRIMARY KEY,
|
||||||
|
"crn" VARCHAR NOT NULL,
|
||||||
|
"subject" VARCHAR NOT NULL,
|
||||||
|
"course_number" VARCHAR NOT NULL,
|
||||||
|
"title" VARCHAR NOT NULL,
|
||||||
|
"term_code" VARCHAR NOT NULL,
|
||||||
|
"enrollment" INT4 NOT NULL,
|
||||||
|
"max_enrollment" INT4 NOT NULL,
|
||||||
|
"wait_count" INT4 NOT NULL,
|
||||||
|
"wait_capacity" INT4 NOT NULL,
|
||||||
|
"last_scraped_at" TIMESTAMPTZ NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "course_metrics"(
|
||||||
|
"id" INT4 NOT NULL PRIMARY KEY,
|
||||||
|
"course_id" INT4 NOT NULL,
|
||||||
|
"timestamp" TIMESTAMPTZ NOT NULL,
|
||||||
|
"enrollment" INT4 NOT NULL,
|
||||||
|
"wait_count" INT4 NOT NULL,
|
||||||
|
"seats_available" INT4 NOT NULL,
|
||||||
|
FOREIGN KEY ("course_id") REFERENCES "courses"("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "course_audits"(
|
||||||
|
"id" INT4 NOT NULL PRIMARY KEY,
|
||||||
|
"course_id" INT4 NOT NULL,
|
||||||
|
"timestamp" TIMESTAMPTZ NOT NULL,
|
||||||
|
"field_changed" VARCHAR NOT NULL,
|
||||||
|
"old_value" TEXT NOT NULL,
|
||||||
|
"new_value" TEXT NOT NULL,
|
||||||
|
FOREIGN KEY ("course_id") REFERENCES "courses"("id")
|
||||||
|
);
|
||||||
|
|
||||||
4
src/data/mod.rs
Normal file
4
src/data/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
//! Database models and schema.
|
||||||
|
|
||||||
|
pub mod models;
|
||||||
|
pub mod schema;
|
||||||
80
src/data/models.rs
Normal file
80
src/data/models.rs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//! Diesel models for the database schema.
|
||||||
|
|
||||||
|
use crate::data::schema::{course_audits, course_metrics, courses};
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use diesel::{Insertable, Queryable, Selectable};
|
||||||
|
|
||||||
|
#[derive(Queryable, Selectable)]
|
||||||
|
#[diesel(table_name = courses)]
|
||||||
|
pub struct Course {
|
||||||
|
pub id: i32,
|
||||||
|
pub crn: String,
|
||||||
|
pub subject: String,
|
||||||
|
pub course_number: String,
|
||||||
|
pub title: String,
|
||||||
|
pub term_code: String,
|
||||||
|
pub enrollment: i32,
|
||||||
|
pub max_enrollment: i32,
|
||||||
|
pub wait_count: i32,
|
||||||
|
pub wait_capacity: i32,
|
||||||
|
pub last_scraped_at: DateTime<Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[diesel(table_name = courses)]
|
||||||
|
pub struct NewCourse<'a> {
|
||||||
|
pub crn: &'a str,
|
||||||
|
pub subject: &'a str,
|
||||||
|
pub course_number: &'a str,
|
||||||
|
pub title: &'a str,
|
||||||
|
pub term_code: &'a str,
|
||||||
|
pub enrollment: i32,
|
||||||
|
pub max_enrollment: i32,
|
||||||
|
pub wait_count: i32,
|
||||||
|
pub wait_capacity: i32,
|
||||||
|
pub last_scraped_at: DateTime<Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Queryable, Selectable)]
|
||||||
|
#[diesel(table_name = course_metrics)]
|
||||||
|
#[diesel(belongs_to(Course))]
|
||||||
|
pub struct CourseMetric {
|
||||||
|
pub id: i32,
|
||||||
|
pub course_id: i32,
|
||||||
|
pub timestamp: DateTime<Utc>,
|
||||||
|
pub enrollment: i32,
|
||||||
|
pub wait_count: i32,
|
||||||
|
pub seats_available: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[diesel(table_name = course_metrics)]
|
||||||
|
pub struct NewCourseMetric {
|
||||||
|
pub course_id: i32,
|
||||||
|
pub timestamp: DateTime<Utc>,
|
||||||
|
pub enrollment: i32,
|
||||||
|
pub wait_count: i32,
|
||||||
|
pub seats_available: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Queryable, Selectable)]
|
||||||
|
#[diesel(table_name = course_audits)]
|
||||||
|
#[diesel(belongs_to(Course))]
|
||||||
|
pub struct CourseAudit {
|
||||||
|
pub id: i32,
|
||||||
|
pub course_id: i32,
|
||||||
|
pub timestamp: DateTime<Utc>,
|
||||||
|
pub field_changed: String,
|
||||||
|
pub old_value: String,
|
||||||
|
pub new_value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[diesel(table_name = course_audits)]
|
||||||
|
pub struct NewCourseAudit<'a> {
|
||||||
|
pub course_id: i32,
|
||||||
|
pub timestamp: DateTime<Utc>,
|
||||||
|
pub field_changed: &'a str,
|
||||||
|
pub old_value: &'a str,
|
||||||
|
pub new_value: &'a str,
|
||||||
|
}
|
||||||
42
src/data/schema.rs
Normal file
42
src/data/schema.rs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
diesel::table! {
|
||||||
|
courses (id) {
|
||||||
|
id -> Int4,
|
||||||
|
crn -> Varchar,
|
||||||
|
subject -> Varchar,
|
||||||
|
course_number -> Varchar,
|
||||||
|
title -> Varchar,
|
||||||
|
term_code -> Varchar,
|
||||||
|
enrollment -> Int4,
|
||||||
|
max_enrollment -> Int4,
|
||||||
|
wait_count -> Int4,
|
||||||
|
wait_capacity -> Int4,
|
||||||
|
last_scraped_at -> Timestamptz,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
course_metrics (id) {
|
||||||
|
id -> Int4,
|
||||||
|
course_id -> Int4,
|
||||||
|
timestamp -> Timestamptz,
|
||||||
|
enrollment -> Int4,
|
||||||
|
wait_count -> Int4,
|
||||||
|
seats_available -> Int4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
course_audits (id) {
|
||||||
|
id -> Int4,
|
||||||
|
course_id -> Int4,
|
||||||
|
timestamp -> Timestamptz,
|
||||||
|
field_changed -> Varchar,
|
||||||
|
old_value -> Text,
|
||||||
|
new_value -> Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::joinable!(course_metrics -> courses (course_id));
|
||||||
|
diesel::joinable!(course_audits -> courses (course_id));
|
||||||
|
|
||||||
|
diesel::allow_tables_to_appear_in_same_query!(courses, course_metrics, course_audits,);
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
pub mod app_state;
|
pub mod app_state;
|
||||||
pub mod banner;
|
pub mod banner;
|
||||||
pub mod bot;
|
pub mod bot;
|
||||||
|
pub mod data;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod services;
|
pub mod services;
|
||||||
pub mod web;
|
pub mod web;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ mod app_state;
|
|||||||
mod banner;
|
mod banner;
|
||||||
mod bot;
|
mod bot;
|
||||||
mod config;
|
mod config;
|
||||||
|
mod data;
|
||||||
mod error;
|
mod error;
|
||||||
mod services;
|
mod services;
|
||||||
mod web;
|
mod web;
|
||||||
|
|||||||
Reference in New Issue
Block a user