orm.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package orm
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/http"
  6. "strings"
  7. "github.com/jinzhu/gorm"
  8. _ "github.com/jinzhu/gorm/dialects/mysql"
  9. )
  10. const (
  11. ADMINISTRATIVE_ROLE_PERSONAL = iota
  12. ADMINISTRATIVE_ROLE_TEACHING
  13. ADMINISTRATIVE_ROLE_DSGA
  14. ADMINISTRATIVE_ROLE_SCHOOL_CARETAKER
  15. ADMINISTRATIVE_ROLE_TECHNICAL_ASSISTANT
  16. ADMINISTRATIVE_ROLE_LIBRARIAN
  17. ADMINISTRATIVE_ROLE_UNDEFINED
  18. IssueTeacherHours = iota
  19. )
  20. type Timetable [][]Activity
  21. type Person interface {
  22. GetCredential() *Credential
  23. }
  24. type TheBoss struct {
  25. gorm.Model
  26. Credential
  27. Teachers []Teacher
  28. }
  29. type Address struct {
  30. City string
  31. Street string
  32. ZipCode string
  33. Country string
  34. }
  35. type Location struct {
  36. Id string
  37. Name string
  38. Address *Address
  39. }
  40. type Room struct {
  41. Id string
  42. Name string
  43. Capacity int
  44. Location *Location
  45. }
  46. type Desk struct {
  47. Id string
  48. Name string
  49. Students []*Student
  50. Teacher *Teacher
  51. }
  52. type Student struct {
  53. gorm.Model
  54. Credential
  55. Class *Class
  56. }
  57. type Director struct {
  58. gorm.Model
  59. Credential
  60. }
  61. type Administrative struct {
  62. gorm.Model
  63. Credential
  64. Role int
  65. }
  66. type Office struct {
  67. gorm.Model
  68. Credential
  69. Persons []Person
  70. }
  71. type Department struct {
  72. gorm.Model
  73. Name string
  74. Subjects []Subject
  75. Teachers []Teacher `gorm:"many2many:department_teachers;"`
  76. }
  77. type GetFn func(map[string]string) (interface{}, error)
  78. type PostFn func(map[string]string, *http.Request) (IDer, error)
  79. var (
  80. currDB *gorm.DB
  81. Get map[string]GetFn = map[string]GetFn{
  82. // Teacher
  83. "/teachers": GetTeachersAll,
  84. "/teachers/{id}": GetTeacherAll,
  85. "/teachers/{id}/update": GetTeacher,
  86. "/teachers/add/": GetNothing,
  87. "/api/teachers": GetTeachersAll,
  88. // Classes
  89. /// HTML
  90. "/classes": GetClassesAll,
  91. "/classes/{id}": GetClassAll,
  92. "/classes/{id}/update": GetClassForUpdate,
  93. "/classes/add/": GetClassForAdd,
  94. /// JSON
  95. "/api/classes": GetClassesAll,
  96. // Subjects
  97. "/subjects": GetSubjectsAll,
  98. "/subjects/{id}": GetSubjectAll,
  99. "/subjects/{id}/update": GetSubjectForUpdate,
  100. "/subjects/add/": GetSubjectForAdd,
  101. "/api/subjects": GetSubjectsAll,
  102. // Activity
  103. "/activities": GetActivitiesAll,
  104. "/activities/{id}": GetActivityAll,
  105. "/activities/{id}/update": GetActivityForUpdate,
  106. "/activities/add/": GetActivityForAdd,
  107. "/api/activities": GetActivitiesAll,
  108. }
  109. Post map[string]PostFn = map[string]PostFn{
  110. // Teacher
  111. /// HTML
  112. "/teachers/{id}/update": UpdateTeacher,
  113. "/teachers/{id}/delete": DeleteTeacher,
  114. "/teachers/add/": AddTeacher,
  115. /// JSON
  116. "/api/teachers/add": AddTeacher,
  117. // Classes
  118. "/classes/{id}/update": UpdateClass,
  119. "/classes/{id}/delete": DeleteClass,
  120. "/classes/add/": AddClass,
  121. // Subjects
  122. "/subjects/{id}/update": UpdateSubject,
  123. "/subjects/{id}/delete": DeleteSubject,
  124. "/subjects/add/": AddSubject,
  125. // Activity
  126. "/activities/{id}/update": UpdateActivity,
  127. "/activities/{id}/delete": DeleteActivity,
  128. "/activities/add/": AddActivity,
  129. }
  130. )
  131. func (b *TheBoss) Create(db *gorm.DB, record map[string]interface{}) error {
  132. if record["role"] == "boss" {
  133. result := new(TheBoss)
  134. result.Name = record["name"].(string)
  135. result.Surname = record["surname"].(string)
  136. result.Username = result.GenerateUsername()
  137. result.Password = result.GenerateSaltedPassword(result.Username)
  138. db.Create(result)
  139. } else {
  140. boss := TheBoss{}
  141. teacher := Teacher{}
  142. db.Model(TheBoss{}).First(&boss)
  143. db.Where("username=?", record["username"]).First(&teacher)
  144. db.Model(&boss).Association("Teachers").Append(&teacher)
  145. }
  146. return nil
  147. }
  148. func (a *Administrative) Create(db *gorm.DB, record map[string]interface{}) error {
  149. result := Administrative{}
  150. result.Name = record["name"].(string)
  151. result.Surname = record["surname"].(string)
  152. result.Username = result.GenerateUsername()
  153. result.Password = result.GenerateSaltedPassword(result.Username)
  154. switch record["role"] {
  155. case "personal_administrator":
  156. result.Role = ADMINISTRATIVE_ROLE_PERSONAL
  157. case "teaching_administrator":
  158. result.Role = ADMINISTRATIVE_ROLE_TEACHING
  159. case "school_caretaker":
  160. result.Role = ADMINISTRATIVE_ROLE_SCHOOL_CARETAKER
  161. case "technical_assistant":
  162. result.Role = ADMINISTRATIVE_ROLE_TECHNICAL_ASSISTANT
  163. case "librarian":
  164. result.Role = ADMINISTRATIVE_ROLE_LIBRARIAN
  165. case "dsga":
  166. result.Role = ADMINISTRATIVE_ROLE_DSGA
  167. default:
  168. result.Role = ADMINISTRATIVE_ROLE_UNDEFINED
  169. }
  170. db.Create(&result)
  171. return nil
  172. }
  173. func (d *Director) Create(db *gorm.DB, record map[string]interface{}) error {
  174. result := new(Director)
  175. if name := record["name"]; name == nil {
  176. return errors.New("Error in creating director: field name is empty")
  177. } else {
  178. result.Name = name.(string)
  179. }
  180. if surname := record["surname"]; surname == nil {
  181. return errors.New("Error in creating director: field surname is empty")
  182. } else {
  183. result.Surname = surname.(string)
  184. }
  185. // Generate username and initial password
  186. result.Username = result.GenerateUsername()
  187. result.Password = result.GenerateSaltedPassword(result.Username)
  188. db.Set("gorm:save_associations", false).Create(result)
  189. return nil
  190. }
  191. func (t *Student) Create(db *gorm.DB, record map[string]interface{}) error {
  192. result := new(Student)
  193. if name := record["name"]; name == nil {
  194. return errors.New("Error in creating student: field name is empty")
  195. } else {
  196. result.Name = name.(string)
  197. }
  198. if surname := record["surname"]; surname == nil {
  199. return errors.New("Error in creating student: field surname is empty")
  200. } else {
  201. result.Surname = surname.(string)
  202. }
  203. // Generate username and initial password
  204. result.Username = result.GenerateUsername()
  205. result.Password = result.GenerateSaltedPassword(result.Username)
  206. db.Set("gorm:save_associations", false).Create(result)
  207. return nil
  208. }
  209. func (d *Department) Create(db *gorm.DB, record map[string]interface{}) error {
  210. result := new(Department)
  211. if name := record["name"]; name == nil {
  212. return errors.New("Error in updating subject: field name is empty")
  213. } else {
  214. result.Name = name.(string)
  215. }
  216. db.Set("gorm:save_associations", false).Create(result)
  217. // Handle department-subjects relationship
  218. for _, s := range record["subjects"].([]interface{}) {
  219. subject := Subject{}
  220. db.Where("name=?", strings.TrimSpace(s.(string))).Find(&subject)
  221. db.Model(result).Association("Subjects").Append(subject)
  222. }
  223. // Handle department-teachers relationship
  224. allTeachers := make([]Teacher, 0)
  225. db.Find(&allTeachers)
  226. for _, t := range allTeachers {
  227. db.Model(&t).Related(&t.Subjects, "Subjects")
  228. for _, s := range t.Subjects {
  229. for _, depS := range result.Subjects {
  230. if s.Name == depS.Name {
  231. db.Model(result).Association("Teachers").Append(t)
  232. }
  233. }
  234. }
  235. }
  236. return nil
  237. }
  238. func New(connection string) (*gorm.DB, error) {
  239. db, err := gorm.Open("mysql", connection)
  240. if err != nil {
  241. return nil, err
  242. }
  243. return db, nil
  244. }
  245. func Use(db *gorm.DB) {
  246. currDB = db
  247. }
  248. func DB() *gorm.DB {
  249. return currDB
  250. }
  251. func Reset() {
  252. currDB.DropTableIfExists(
  253. &School{},
  254. &Subject{},
  255. &Teacher{},
  256. &Class{},
  257. &Activity{},
  258. &Student{},
  259. &Department{},
  260. &TheBoss{},
  261. &Administrative{},
  262. &Director{},
  263. &Issue{},
  264. )
  265. }
  266. func AutoMigrate() {
  267. if err := currDB.AutoMigrate(
  268. &School{},
  269. &Subject{},
  270. &Teacher{},
  271. &Class{},
  272. &Activity{},
  273. &Department{},
  274. &TheBoss{},
  275. &Administrative{},
  276. &Student{},
  277. &Director{},
  278. &Issue{},
  279. ).Error; err != nil {
  280. panic(err)
  281. }
  282. }
  283. func GetTeacherByUsername(username string) (*Teacher, error) {
  284. teacher := Teacher{}
  285. currDB.Where(fmt.Sprintf("username='%s'", username)).Find(&teacher)
  286. return &teacher, nil
  287. }