package orm import ( "errors" "fmt" "net/http" "strings" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) const ( ADMINISTRATIVE_ROLE_PERSONAL = iota ADMINISTRATIVE_ROLE_TEACHING ADMINISTRATIVE_ROLE_DSGA ADMINISTRATIVE_ROLE_SCHOOL_CARETAKER ADMINISTRATIVE_ROLE_TECHNICAL_ASSISTANT ADMINISTRATIVE_ROLE_LIBRARIAN ADMINISTRATIVE_ROLE_UNDEFINED IssueTeacherHours = iota ) type Timetable [][]Activity type Person interface { GetCredential() *Credential } type TheBoss struct { gorm.Model Credential Teachers []Teacher } type Address struct { City string Street string ZipCode string Country string } type Location struct { Id string Name string Address *Address } type Room struct { Id string Name string Capacity int Location *Location } type Desk struct { Id string Name string Students []*Student Teacher *Teacher } type Student struct { gorm.Model Credential Class *Class } type Director struct { gorm.Model Credential } type Administrative struct { gorm.Model Credential Role int } type Office struct { gorm.Model Credential Persons []Person } type Department struct { gorm.Model Name string Subjects []Subject Teachers []Teacher `gorm:"many2many:department_teachers;"` } type GetFn func(map[string]string) (interface{}, error) type PostFn func(map[string]string, *http.Request) (IDer, error) var ( currDB *gorm.DB Get map[string]GetFn = map[string]GetFn{ // Teacher "/teachers": GetTeachersAll, "/teachers/{id}": GetTeacherAll, "/teachers/{id}/update": GetTeacher, "/teachers/add/": GetNothing, "/api/teachers": GetTeachersAll, // Classes "/classes": GetClassesAll, "/classes/{id}": GetClassAll, "/classes/{id}/update": GetClassForUpdate, "/classes/add/": GetClassForAdd, "/api/classes": GetClassesAll, // Subjects "/subjects": GetSubjectsAll, "/subjects/{id}": GetSubjectAll, "/subjects/{id}/update": GetSubjectForUpdate, "/subjects/add/": GetSubjectForAdd, "/api/subjects": GetSubjectsAll, // Activity "/activities": GetActivitiesAll, "/activities/{id}": GetActivityAll, "/activities/{id}/update": GetActivityForUpdate, "/activities/add/": GetActivityForAdd, "/api/activities": GetActivitiesAll, } Post map[string]PostFn = map[string]PostFn{ // Teacher "/teachers/{id}/update": UpdateTeacher, "/teachers/{id}/delete": DeleteTeacher, "/teachers/add/": AddTeacher, // Classes "/classes/{id}/update": UpdateClass, "/classes/{id}/delete": DeleteClass, "/classes/add/": AddClass, // Subjects "/subjects/{id}/update": UpdateSubject, "/subjects/{id}/delete": DeleteSubject, "/subjects/add/": AddSubject, // Activity "/activities/{id}/update": UpdateActivity, "/activities/{id}/delete": DeleteActivity, "/activities/add/": AddActivity, } ) func (b *TheBoss) Create(db *gorm.DB, record map[string]interface{}) error { if record["role"] == "boss" { result := new(TheBoss) result.Name = record["name"].(string) result.Surname = record["surname"].(string) result.Username = result.GenerateUsername() result.Password = result.GenerateSaltedPassword(result.Username) db.Create(result) } else { boss := TheBoss{} teacher := Teacher{} db.Model(TheBoss{}).First(&boss) db.Where("username=?", record["username"]).First(&teacher) db.Model(&boss).Association("Teachers").Append(&teacher) } return nil } func (a *Administrative) Create(db *gorm.DB, record map[string]interface{}) error { result := Administrative{} result.Name = record["name"].(string) result.Surname = record["surname"].(string) result.Username = result.GenerateUsername() result.Password = result.GenerateSaltedPassword(result.Username) switch record["role"] { case "personal_administrator": result.Role = ADMINISTRATIVE_ROLE_PERSONAL case "teaching_administrator": result.Role = ADMINISTRATIVE_ROLE_TEACHING case "school_caretaker": result.Role = ADMINISTRATIVE_ROLE_SCHOOL_CARETAKER case "technical_assistant": result.Role = ADMINISTRATIVE_ROLE_TECHNICAL_ASSISTANT case "librarian": result.Role = ADMINISTRATIVE_ROLE_LIBRARIAN case "dsga": result.Role = ADMINISTRATIVE_ROLE_DSGA default: result.Role = ADMINISTRATIVE_ROLE_UNDEFINED } db.Create(&result) return nil } func (d *Director) Create(db *gorm.DB, record map[string]interface{}) error { result := new(Director) if name := record["name"]; name == nil { return errors.New("Error in creating director: field name is empty") } else { result.Name = name.(string) } if surname := record["surname"]; surname == nil { return errors.New("Error in creating director: field surname is empty") } else { result.Surname = surname.(string) } // Generate username and initial password result.Username = result.GenerateUsername() result.Password = result.GenerateSaltedPassword(result.Username) db.Set("gorm:save_associations", false).Create(result) return nil } func (t *Student) Create(db *gorm.DB, record map[string]interface{}) error { result := new(Student) if name := record["name"]; name == nil { return errors.New("Error in creating student: field name is empty") } else { result.Name = name.(string) } if surname := record["surname"]; surname == nil { return errors.New("Error in creating student: field surname is empty") } else { result.Surname = surname.(string) } // Generate username and initial password result.Username = result.GenerateUsername() result.Password = result.GenerateSaltedPassword(result.Username) db.Set("gorm:save_associations", false).Create(result) return nil } func (d *Department) Create(db *gorm.DB, record map[string]interface{}) error { result := new(Department) if name := record["name"]; name == nil { return errors.New("Error in updating subject: field name is empty") } else { result.Name = name.(string) } db.Set("gorm:save_associations", false).Create(result) // Handle department-subjects relationship for _, s := range record["subjects"].([]interface{}) { subject := Subject{} db.Where("name=?", strings.TrimSpace(s.(string))).Find(&subject) db.Model(result).Association("Subjects").Append(subject) } // Handle department-teachers relationship allTeachers := make([]Teacher, 0) db.Find(&allTeachers) for _, t := range allTeachers { db.Model(&t).Related(&t.Subjects, "Subjects") for _, s := range t.Subjects { for _, depS := range result.Subjects { if s.Name == depS.Name { db.Model(result).Association("Teachers").Append(t) } } } } return nil } func New(connection string) (*gorm.DB, error) { db, err := gorm.Open("mysql", connection) if err != nil { return nil, err } return db, nil } func Use(db *gorm.DB) { currDB = db } func DB() *gorm.DB { return currDB } func Reset() { currDB.DropTableIfExists( &School{}, &Subject{}, &Teacher{}, &Class{}, &Activity{}, &Student{}, &Department{}, &TheBoss{}, &Administrative{}, &Director{}, &Issue{}, ) } func AutoMigrate() { if err := currDB.AutoMigrate( &School{}, &Subject{}, &Teacher{}, &Class{}, &Activity{}, &Department{}, &TheBoss{}, &Administrative{}, &Student{}, &Director{}, &Issue{}, ).Error; err != nil { panic(err) } } func GetTeacherByUsername(username string) (*Teacher, error) { teacher := Teacher{} currDB.Where(fmt.Sprintf("username='%s'", username)).Find(&teacher) return &teacher, nil }