Skip to content

Commit 3ed9a39

Browse files
committed
db: normalize courseInfo
1 parent 8e78d4a commit 3ed9a39

File tree

7 files changed

+196
-128
lines changed

7 files changed

+196
-128
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
"prettier": "^3.3.3",
1818
"turbo": "^2.1.2"
1919
},
20-
"packageManager": "pnpm@9.11.0"
20+
"packageManager": "pnpm@9.12.1"
2121
}

packages/database/drizzle/0000_shocking_the_santerians.sql renamed to packages/database/drizzle/0000_damp_lilandra.sql

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,30 @@ CREATE TABLE IF NOT EXISTS "course" (
4040
"academic_year" integer NOT NULL,
4141
"semester" "semester" NOT NULL,
4242
"course_no" text NOT NULL,
43-
"abbr_name" text NOT NULL,
44-
"course_name_en" text NOT NULL,
45-
"course_name_th" text NOT NULL,
46-
"course_desc_en" text,
47-
"course_desc_th" text,
48-
"faculty" text NOT NULL,
49-
"department" text NOT NULL,
50-
"credit" numeric NOT NULL,
51-
"credit_hours" text NOT NULL,
5243
"course_condition" text,
5344
"midterm_start" timestamp,
5445
"midterm_end" timestamp,
5546
"final_start" timestamp,
5647
"final_end" timestamp,
5748
"gen_ed_type" "gen_ed_type" DEFAULT 'NO' NOT NULL,
58-
"rating" double precision,
5949
"created_at" timestamp DEFAULT now() NOT NULL,
6050
"updated_at" timestamp DEFAULT now() NOT NULL,
6151
CONSTRAINT "course_unique" UNIQUE("study_program","academic_year","semester","course_no")
6252
);
6353
--> statement-breakpoint
54+
CREATE TABLE IF NOT EXISTS "course_info" (
55+
"course_no" text PRIMARY KEY NOT NULL,
56+
"abbr_name" text NOT NULL,
57+
"course_name_en" text NOT NULL,
58+
"course_name_th" text NOT NULL,
59+
"course_desc_en" text,
60+
"course_desc_th" text,
61+
"faculty" text NOT NULL,
62+
"department" text NOT NULL,
63+
"credit" numeric NOT NULL,
64+
"credit_hours" text NOT NULL
65+
);
66+
--> statement-breakpoint
6467
CREATE TABLE IF NOT EXISTS "course_section" (
6568
"id" text PRIMARY KEY NOT NULL,
6669
"course_id" text NOT NULL,
@@ -146,6 +149,12 @@ CREATE TABLE IF NOT EXISTS "user" (
146149
CONSTRAINT "user_google_id_unique" UNIQUE("google_id")
147150
);
148151
--> statement-breakpoint
152+
DO $$ BEGIN
153+
ALTER TABLE "course" ADD CONSTRAINT "course_course_no_course_info_course_no_fk" FOREIGN KEY ("course_no") REFERENCES "public"."course_info"("course_no") ON DELETE no action ON UPDATE no action;
154+
EXCEPTION
155+
WHEN duplicate_object THEN null;
156+
END $$;
157+
--> statement-breakpoint
149158
DO $$ BEGIN
150159
ALTER TABLE "course_section" ADD CONSTRAINT "course_section_course_id_course_id_fk" FOREIGN KEY ("course_id") REFERENCES "public"."course"("id") ON DELETE no action ON UPDATE no action;
151160
EXCEPTION

packages/database/drizzle/meta/0000_snapshot.json

Lines changed: 86 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"id": "e865a62d-1e0a-4578-9cfd-b44fbbee2d6f",
2+
"id": "101832e8-626d-434f-bbb9-fd1b0f87f781",
33
"prevId": "00000000-0000-0000-0000-000000000000",
44
"version": "7",
55
"dialect": "postgresql",
@@ -40,60 +40,6 @@
4040
"primaryKey": false,
4141
"notNull": true
4242
},
43-
"abbr_name": {
44-
"name": "abbr_name",
45-
"type": "text",
46-
"primaryKey": false,
47-
"notNull": true
48-
},
49-
"course_name_en": {
50-
"name": "course_name_en",
51-
"type": "text",
52-
"primaryKey": false,
53-
"notNull": true
54-
},
55-
"course_name_th": {
56-
"name": "course_name_th",
57-
"type": "text",
58-
"primaryKey": false,
59-
"notNull": true
60-
},
61-
"course_desc_en": {
62-
"name": "course_desc_en",
63-
"type": "text",
64-
"primaryKey": false,
65-
"notNull": false
66-
},
67-
"course_desc_th": {
68-
"name": "course_desc_th",
69-
"type": "text",
70-
"primaryKey": false,
71-
"notNull": false
72-
},
73-
"faculty": {
74-
"name": "faculty",
75-
"type": "text",
76-
"primaryKey": false,
77-
"notNull": true
78-
},
79-
"department": {
80-
"name": "department",
81-
"type": "text",
82-
"primaryKey": false,
83-
"notNull": true
84-
},
85-
"credit": {
86-
"name": "credit",
87-
"type": "numeric",
88-
"primaryKey": false,
89-
"notNull": true
90-
},
91-
"credit_hours": {
92-
"name": "credit_hours",
93-
"type": "text",
94-
"primaryKey": false,
95-
"notNull": true
96-
},
9743
"course_condition": {
9844
"name": "course_condition",
9945
"type": "text",
@@ -132,12 +78,6 @@
13278
"notNull": true,
13379
"default": "'NO'"
13480
},
135-
"rating": {
136-
"name": "rating",
137-
"type": "double precision",
138-
"primaryKey": false,
139-
"notNull": false
140-
},
14181
"created_at": {
14282
"name": "created_at",
14383
"type": "timestamp",
@@ -154,7 +94,21 @@
15494
}
15595
},
15696
"indexes": {},
157-
"foreignKeys": {},
97+
"foreignKeys": {
98+
"course_course_no_course_info_course_no_fk": {
99+
"name": "course_course_no_course_info_course_no_fk",
100+
"tableFrom": "course",
101+
"tableTo": "course_info",
102+
"columnsFrom": [
103+
"course_no"
104+
],
105+
"columnsTo": [
106+
"course_no"
107+
],
108+
"onDelete": "no action",
109+
"onUpdate": "no action"
110+
}
111+
},
158112
"compositePrimaryKeys": {},
159113
"uniqueConstraints": {
160114
"course_unique": {
@@ -169,6 +123,76 @@
169123
}
170124
}
171125
},
126+
"public.course_info": {
127+
"name": "course_info",
128+
"schema": "",
129+
"columns": {
130+
"course_no": {
131+
"name": "course_no",
132+
"type": "text",
133+
"primaryKey": true,
134+
"notNull": true
135+
},
136+
"abbr_name": {
137+
"name": "abbr_name",
138+
"type": "text",
139+
"primaryKey": false,
140+
"notNull": true
141+
},
142+
"course_name_en": {
143+
"name": "course_name_en",
144+
"type": "text",
145+
"primaryKey": false,
146+
"notNull": true
147+
},
148+
"course_name_th": {
149+
"name": "course_name_th",
150+
"type": "text",
151+
"primaryKey": false,
152+
"notNull": true
153+
},
154+
"course_desc_en": {
155+
"name": "course_desc_en",
156+
"type": "text",
157+
"primaryKey": false,
158+
"notNull": false
159+
},
160+
"course_desc_th": {
161+
"name": "course_desc_th",
162+
"type": "text",
163+
"primaryKey": false,
164+
"notNull": false
165+
},
166+
"faculty": {
167+
"name": "faculty",
168+
"type": "text",
169+
"primaryKey": false,
170+
"notNull": true
171+
},
172+
"department": {
173+
"name": "department",
174+
"type": "text",
175+
"primaryKey": false,
176+
"notNull": true
177+
},
178+
"credit": {
179+
"name": "credit",
180+
"type": "numeric",
181+
"primaryKey": false,
182+
"notNull": true
183+
},
184+
"credit_hours": {
185+
"name": "credit_hours",
186+
"type": "text",
187+
"primaryKey": false,
188+
"notNull": true
189+
}
190+
},
191+
"indexes": {},
192+
"foreignKeys": {},
193+
"compositePrimaryKeys": {},
194+
"uniqueConstraints": {}
195+
},
172196
"public.course_section": {
173197
"name": "course_section",
174198
"schema": "",

packages/database/drizzle/meta/_journal.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
{
66
"idx": 0,
77
"version": "7",
8-
"when": 1727199154437,
9-
"tag": "0000_shocking_the_santerians",
8+
"when": 1728806337421,
9+
"tag": "0000_damp_lilandra",
1010
"breakpoints": true
1111
}
1212
]

packages/database/src/schema/courseData.ts

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@ import { createId } from '@paralleldrive/cuid2'
22
import {
33
boolean,
44
decimal,
5-
doublePrecision,
65
integer,
7-
pgEnum,
86
pgTable,
97
text,
108
timestamp,
119
unique,
1210
} from 'drizzle-orm/pg-core'
1311

14-
import { genEdType, semester, studyProgram } from './types.js'
12+
import { dayOfWeek, genEdType, semester, studyProgram } from './types.js'
1513

1614
/**
1715
* https://datagateway.chula.ac.th (Connect to Chula Wi-Fi)
@@ -34,29 +32,9 @@ export const course = pgTable(
3432
semester: semester('semester').notNull(),
3533

3634
// 3 COURSECODE / 11 courseno
37-
courseNo: text('course_no').notNull(),
38-
// 4 COURSENAME
39-
abbrName: text('abbr_name').notNull(),
40-
41-
// 14 coursename_en
42-
courseNameEn: text('course_name_en').notNull(),
43-
// 13 coursename_th
44-
courseNameTh: text('course_name_th').notNull(),
45-
46-
// 23 coursedescription_en
47-
courseDescEn: text('course_desc_en'),
48-
// 22 coursedescription_th
49-
courseDescTh: text('course_desc_th'),
50-
51-
// indirect -> 30 FACCODE or From CourseNo (Transitive Dependency)
52-
faculty: text('faculty').notNull(),
53-
// indirect -> From CourseNo (Transitive Dependency)
54-
department: text('department').notNull(),
55-
56-
// 24 TOTALCREDIT
57-
credit: decimal('credit').notNull(),
58-
// Must build from 17 lcredit 18 nlcredit 19 lhour 20 nlhour 21 shour
59-
creditHours: text('credit_hours').notNull(),
35+
courseNo: text('course_no')
36+
.notNull()
37+
.references(() => courseInfo.courseNo),
6038

6139
// ! not available in data gateway
6240
courseCondition: text('course_condition'),
@@ -72,9 +50,6 @@ export const course = pgTable(
7250
// From section rows OR from gened override?
7351
genEdType: genEdType('gen_ed_type').notNull().default('NO'),
7452

75-
// CU Get Reg's User Data
76-
rating: doublePrecision('rating'),
77-
7853
createdAt: timestamp('created_at').notNull().defaultNow(),
7954
updatedAt: timestamp('updated_at')
8055
.notNull()
@@ -91,6 +66,34 @@ export const course = pgTable(
9166
}),
9267
)
9368

69+
export const courseInfo = pgTable('course_info', {
70+
courseNo: text('course_no').primaryKey(),
71+
72+
// 4 COURSENAME
73+
abbrName: text('abbr_name').notNull(),
74+
75+
// 14 coursename_en
76+
courseNameEn: text('course_name_en').notNull(),
77+
// 13 coursename_th
78+
courseNameTh: text('course_name_th').notNull(),
79+
80+
// 23 coursedescription_en
81+
courseDescEn: text('course_desc_en'),
82+
// 22 coursedescription_th
83+
courseDescTh: text('course_desc_th'),
84+
85+
// TODO separate this into other table
86+
// indirect -> 30 FACCODE or From CourseNo (Transitive Dependency)
87+
faculty: text('faculty').notNull(),
88+
// indirect -> From CourseNo (Transitive Dependency)
89+
department: text('department').notNull(),
90+
91+
// 24 TOTALCREDIT
92+
credit: decimal('credit').notNull(),
93+
// Must build from 17 lcredit 18 nlcredit 19 lhour 20 nlhour 21 shour
94+
creditHours: text('credit_hours').notNull(),
95+
})
96+
9497
export const section = pgTable(
9598
'course_section',
9699
{
@@ -127,18 +130,6 @@ export const section = pgTable(
127130
}),
128131
)
129132

130-
export const dayOfWeek = pgEnum('day_of_week', [
131-
'MO',
132-
'TU',
133-
'WE',
134-
'TH',
135-
'FR',
136-
'SA',
137-
'SU',
138-
'AR',
139-
'IA',
140-
])
141-
142133
export const sectionClass = pgTable('course_class', {
143134
id: text('id')
144135
.primaryKey()

packages/database/src/schema/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,15 @@ import { pgEnum } from 'drizzle-orm/pg-core'
33
export const semester = pgEnum('semester', ['1', '2', '3'])
44
export const studyProgram = pgEnum('study_program', ['S', 'T', 'I'])
55
export const genEdType = pgEnum('gen_ed_type', ['NO', 'SC', 'SO', 'HU', 'IN'])
6+
7+
export const dayOfWeek = pgEnum('day_of_week', [
8+
'MO',
9+
'TU',
10+
'WE',
11+
'TH',
12+
'FR',
13+
'SA',
14+
'SU',
15+
'AR',
16+
'IA',
17+
])

0 commit comments

Comments
 (0)