Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions cmd/app/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package main

import (
"assignment_1_gorm"
"fmt"

"gorm.io/driver/mysql"
"gorm.io/gorm"
)

// main connects to database and does the exercises in sol-1.sql and sol-2.sql
func main() {
// Connect to the MySQL database
dsn := "quangmx:2511@tcp(127.0.0.1:3306)/engineerpro?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("Failed to connect to database")
}

initDatabase(db)

// Những cặp student-professor có dạy học nhau và số lớp mà họ có liên quan
related_stud_prof(db)

// Những course (distinct) mà 1 professor cụ thể đang dạy
teaching_courses(db, 1)

// // TODO: Implement this
// // Những course (distinct) mà 1 student cụ thể đang học
// studying_courses(db, 1)

// // TODO: Implement this
// // điểm số là A, B, C, D, E, F tương đương với 10, 8, 6, 4, 2, 0
// convert_grade(db)

// // TODO: Implement this
// // điểm số trung bình của 1 học sinh cụ thể (quy ra lại theo chữ cái, và xếp loại học lực (weak nếu avg < 5, average nếu >=5 < 8, good nếu >=8 )
// stud_avg_grade(db, 1)

// // TODO: Implement this
// // điểm số trung bình của các class (quy ra lại theo chữ cái)
// class_avg_grade(db)

// // TODO: Implement this
// // điểm số trung bình của các course (quy ra lại theo chữ cái)
// course_avg_grade(db)

}

// initDatabase creates tables and adds records
func initDatabase(db *gorm.DB) {
// Delete tables if existed
db.Migrator().DropTable(&assignment_1_gorm.Professor{})
db.Migrator().DropTable(&assignment_1_gorm.Student{})
db.Migrator().DropTable(&assignment_1_gorm.Course{})
db.Migrator().DropTable(&assignment_1_gorm.Class{})
db.Migrator().DropTable(&assignment_1_gorm.Enroll{})
fmt.Println("Tables deleted successfully...")

// Create tables
db.Migrator().CreateTable(&assignment_1_gorm.Professor{})
db.Migrator().CreateTable(&assignment_1_gorm.Student{})
db.Migrator().CreateTable(&assignment_1_gorm.Course{})
db.Migrator().CreateTable(&assignment_1_gorm.Class{})
db.Migrator().CreateTable(&assignment_1_gorm.Enroll{})
fmt.Println("Tables created successfully...")

// Create records
var result *gorm.DB
professors := []assignment_1_gorm.Professor{
{FirstName: "Albus", LastName: "Dumbledore"},
{FirstName: "Severus", LastName: "Snape"},
{FirstName: "Alastor", LastName: "Moody"},
}
result = db.Create(&professors)
if result.Error != nil {
panic(result.Error)
}

students := []assignment_1_gorm.Student{
{FirstName: "Harry", LastName: "Potter", Street: "Privet Drive 1", City: "London", Zip: "100000"},
{FirstName: "Hermione", LastName: "Granger", Street: "Privet Drive 2", City: "London", Zip: "200000"},
{FirstName: "Ron", LastName: "Weasly", Street: "Privet Drive 3", City: "London", Zip: "300000"},
}
result = db.Create(&students)
if result.Error != nil {
panic(result.Error)
}

courses := []assignment_1_gorm.Course{
{Name: "Physical Education"},
{Name: "Quidditch"},
{Name: "Defence Against the Dark Arts"},
{Name: "Potion"},
}
result = db.Create(&courses)
if result.Error != nil {
panic(result.Error)
}

classes := []assignment_1_gorm.Class{
{Name: "PE1", ProfessorID: 1, CourseID: 1, RoomLoc: "001", RoomCap: "100"},
{Name: "QD1", ProfessorID: 2, CourseID: 2, RoomLoc: "002", RoomCap: "200"},
{Name: "DA1", ProfessorID: 3, CourseID: 3, RoomLoc: "003", RoomCap: "300"},
{Name: "DA2", ProfessorID: 3, CourseID: 3, RoomLoc: "004", RoomCap: "400"},
{Name: "PT1", ProfessorID: 3, CourseID: 4, RoomLoc: "005", RoomCap: "500"},
}
result = db.Create(&classes)
if result.Error != nil {
panic(result.Error)
}

enrolls := []assignment_1_gorm.Enroll{
{StudentID: 1, ClassID: 2, Grade: "B"},
{StudentID: 2, ClassID: 1, Grade: "A"},
{StudentID: 2, ClassID: 2, Grade: "A"},
{StudentID: 2, ClassID: 3, Grade: "A"},
{StudentID: 3, ClassID: 1, Grade: "C"},
{StudentID: 3, ClassID: 3, Grade: "D"},
{StudentID: 1, ClassID: 4, Grade: "D"},
{StudentID: 2, ClassID: 4, Grade: "D"},
{StudentID: 3, ClassID: 4, Grade: "D"},
}
result = db.Create(&enrolls)
if result.Error != nil {
panic(result.Error)
}

fmt.Println("Records created successfully...")
}

// Những cặp student-professor có dạy học nhau và số lớp mà họ có liên quan
func related_stud_prof(db *gorm.DB) {
type Record struct {
StudentID int `gorm:"column:stud_id"`
ProfessorID int `gorm:"column:prof_id"`
Count int `gorm:"column:num_class"`
}
var records []Record
query := `
select
distinct stud_id,
prof_id,
count(*) as num_class
from
Class
join Enroll using (class_id)
group by
stud_id,
prof_id
order by
stud_id;`
db.Raw(query).Scan(&records)

// Print to console
fmt.Println("\nNhững cặp student-professor có dạy học nhau và số lớp mà họ có liên quan")
for _, record := range records {
fmt.Printf("%+v\n", record)
}
}

// Những course (distinct) mà 1 professor cụ thể đang dạy
func teaching_courses(db *gorm.DB, prof_id int) {
type Record struct {
CourseID int `gorm:"column:course_id"`
}
var records []Record
query := `
select
distinct course_id
from
Class
where
prof_id = ?;`
db.Raw(query, prof_id).Scan(&records)

// Print to console
fmt.Printf("\nNhững course (distinct) mà professor %d đang dạy\n", prof_id)
for _, record := range records {
fmt.Printf("%+v\n", record)
}
}
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module assignment_1_gorm

go 1.20

require gorm.io/gorm v1.25.1

require github.com/go-sql-driver/mysql v1.7.0 // indirect

require (
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
gorm.io/driver/mysql v1.5.1
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
112 changes: 112 additions & 0 deletions model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package assignment_1_gorm

// CREATE TABLE Professor (
//
// prof_id INT AUTO_INCREMENT,
// prof_fname VARCHAR(50),
// prof_lname VARCHAR(50),
// PRIMARY KEY (prof_id)
//
// );
type Professor struct {
ID uint32 `gorm:"column:prof_id;type:int(32);primary_key;auto_increment"`
FirstName string `gorm:"column:prof_fname;type:varchar(50)"`
LastName string `gorm:"column:prof_lname;type:varchar(50)"`
}

func (Professor) TableName() string {
return "Professor"
}

// CREATE TABLE Student (
//
// stud_id INT AUTO_INCREMENT,
// stud_fname VARCHAR(50),
// stud_lname VARCHAR(50),
// stud_street VARCHAR(255),
// stud_city VARCHAR(50),
// stud_zip VARCHAR(10),
// PRIMARY KEY (stud_id)
//
// );
type Student struct {
ID uint32 `gorm:"column:stud_id;type:int(32);primary_key;auto_increment"`
FirstName string `gorm:"column:stud_fname;type:varchar(50)"`
LastName string `gorm:"column:stud_lname;type:varchar(50)"`
Street string `gorm:"column:stud_street;type:varchar(255)"`
City string `gorm:"column:stud_city;type:varchar(50)"`
Zip string `gorm:"column:stud_zip;type:varchar(10)"`
}

func (Student) TableName() string {
return "Student"
}

// CREATE TABLE Course (
//
// course_id INT AUTO_INCREMENT,
// course_name VARCHAR(255),
// PRIMARY KEY (course_id)
//
// );
type Course struct {
ID uint32 `gorm:"column:course_id;type:int(32);primary_key;auto_increment"`
Name string `gorm:"column:course_name;type:varchar(255)"`
}

func (Course) TableName() string {
return "Course"
}

// -- Class and Room are joined into 1 table Class
// CREATE TABLE Class (
//
// class_id INT AUTO_INCREMENT,
// class_name VARCHAR(255),
// prof_id INT,
// course_id INT,
// room_loc VARCHAR(50),
// room_cap VARCHAR(50),
// PRIMARY KEY (class_id),
// FOREIGN KEY (prof_id) REFERENCES Professor(prof_id),
// FOREIGN KEY (course_id) REFERENCES Course(course_id)
//
// );
type Class struct {
ID uint32 `gorm:"column:class_id;type:int(32);primary_key;auto_increment"`
Name string `gorm:"column:class_name;type:varchar(255)"`
ProfessorID uint32 `gorm:"column:prof_id;type:int(32)"`
CourseID uint32 `gorm:"column:course_id;type:int(32)"`
RoomLoc string `gorm:"column:room_loc;type:varchar(50)"`
RoomCap string `gorm:"column:room_cap;type:varchar(50)"`

Professor Professor `gorm:"foreign_key:prof_id;references:prof_id"`
Course Course `gorm:"foreign_key:course_id;references:course_id"`
}

func (Class) TableName() string {
return "Class"
}

// CREATE TABLE Enroll (
//
// stud_id INT,
// class_id INT,
// grade VARCHAR(3),
// PRIMARY KEY (stud_id, class_id),
// FOREIGN KEY (stud_id) REFERENCES Student(stud_id),
// FOREIGN KEY (class_id) REFERENCES Class(class_id)
//
// );
type Enroll struct {
StudentID int `gorm:"column:stud_id;type:int(32);primary_key"`
ClassID int `gorm:"column:class_id;type:int(32);primary_key"`
Grade string `gorm:"column:grade;type:varchar(3)"`

Student Student `gorm:"foreign_key:stud_id;references:stud_id"`
Class Class `gorm:"foreign_key:class_id;references:class_id"`
}

func (Enroll) TableName() string {
return "Enroll"
}
39 changes: 39 additions & 0 deletions sol-1.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-- Solution for Capital Gain/Loss
select
stock_name,
sum(
case
when operation = "Buy" then - price
else price
end
) as capital_gain_loss
from
Stocks
group by
stock_name;

-- Solution for Count Salary Categories
select
"Low Salary" as "category",
count(*) as "accounts_count"
from
Accounts
where
Accounts.income < 20000
union
select
"Average Salary" as "category",
count(*) as "accounts_count"
from
Accounts
where
income >= 20000
and income <= 50000
union
select
"High Salary" as "category",
count(*) as "accounts_count"
from
Accounts
where
income > 50000;
Loading