orm.go 7.7 KB

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