Datenbanken, erster Versuch
This commit is contained in:
parent
b26544756a
commit
766aedf22d
21 changed files with 678 additions and 320 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -6,6 +6,9 @@
|
||||||
*.dylib
|
*.dylib
|
||||||
sprechstundentool
|
sprechstundentool
|
||||||
|
|
||||||
|
#Databases
|
||||||
|
*.db
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
|
||||||
|
@ -17,3 +20,5 @@ vendor/
|
||||||
|
|
||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
go.mod
|
||||||
|
go.sum
|
||||||
|
|
77
controllers/handlers.go
Normal file
77
controllers/handlers.go
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
"sprechstundentool/models"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BaseHandler will hold everything that controller needs
|
||||||
|
type BaseHandler struct {
|
||||||
|
roomRepo models.RoomRepository
|
||||||
|
officeHourRepo models.OfficeHourRepository
|
||||||
|
courseRepo models.CourseRepository
|
||||||
|
tutorRepo models.TutorRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBaseHandler returns a new BaseHandler
|
||||||
|
func NewBaseHandler(roomRepo models.RoomRepository, officeHourRepo models.OfficeHourRepository, courseRepo models.CourseRepository, tutorRepo models.TutorRepository) *BaseHandler {
|
||||||
|
return &BaseHandler{roomRepo, officeHourRepo, courseRepo, tutorRepo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseHandler) RootHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
|
b.writeTimetablePage(w, req, template.HTML(""))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseHandler) GetByRoomHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
|
roomId, _ := strconv.Atoi(req.FormValue("raum"))
|
||||||
|
room, err := b.roomRepo.FindById(roomId)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
b.RootHandler(w, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
officeHours, _ := b.officeHourRepo.FindByRoom(room)
|
||||||
|
b.writeTimetablePage(w, req, printTimetable(GetTimetable(officeHours)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
|
courseid, err := strconv.Atoi(req.FormValue("veranstaltung"))
|
||||||
|
if err != nil {
|
||||||
|
b.RootHandler(w, req)
|
||||||
|
}
|
||||||
|
course, err := b.courseRepo.FindById(courseid)
|
||||||
|
if err != nil {
|
||||||
|
b.RootHandler(w, req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
officeHours, _ := b.officeHourRepo.FindByCourse(course)
|
||||||
|
b.writeTimetablePage(w, req, printTimetable(GetTimetable(officeHours)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseHandler) writeTimetablePage(w http.ResponseWriter, req *http.Request, timetable template.HTML) {
|
||||||
|
courses, _ := b.courseRepo.GetAll()
|
||||||
|
rooms, _ := b.roomRepo.GetAll()
|
||||||
|
selectedRoom, _ := strconv.Atoi(req.FormValue("raum"))
|
||||||
|
selectedCourse, _ := strconv.Atoi(req.FormValue("veranstaltung"))
|
||||||
|
data := struct {
|
||||||
|
Courses []models.Course
|
||||||
|
Rooms []models.Room
|
||||||
|
Timetable template.HTML
|
||||||
|
SelectedRoom int
|
||||||
|
SelectedCourse int
|
||||||
|
}{courses, rooms, timetable, selectedRoom, selectedCourse}
|
||||||
|
tmpl, err := template.ParseFiles("templates/index.html")
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error()))))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = tmpl.Execute(w, data)
|
||||||
|
if err != nil {
|
||||||
|
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error()))))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
137
controllers/timetable.go
Normal file
137
controllers/timetable.go
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// timetable.go
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"sprechstundentool/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetTimetable(officeHours []models.OfficeHour) (timetable map[models.Date]map[int]models.OfficeHour, slots []int) {
|
||||||
|
var fullTimetable = make(map[models.Date]map[int]models.OfficeHour)
|
||||||
|
for _, officeHour := range officeHours {
|
||||||
|
var slot int = 0
|
||||||
|
for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // find slot id
|
||||||
|
_, exists := fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}]
|
||||||
|
if exists {
|
||||||
|
_, exists := fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot]
|
||||||
|
if exists {
|
||||||
|
slot += 1
|
||||||
|
minute = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] = make(map[int]models.OfficeHour)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // write officeHour id to timetable
|
||||||
|
fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] = officeHour
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slots = []int{1, 1, 1, 1, 1}
|
||||||
|
for date, _ := range fullTimetable {
|
||||||
|
if slots[date.Day] < len(fullTimetable[date]) {
|
||||||
|
slots[date.Day] = len(fullTimetable[date])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timetable = make(map[models.Date]map[int]models.OfficeHour)
|
||||||
|
for _, officeHour := range officeHours {
|
||||||
|
for slot := 0; slot < slots[officeHour.Date.Day]; slot += 1 {
|
||||||
|
if fullTimetable[officeHour.Date][slot] == officeHour {
|
||||||
|
timetable[officeHour.Date] = make(map[int]models.OfficeHour)
|
||||||
|
timetable[officeHour.Date][slot] = officeHour
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fullTimetable, slots
|
||||||
|
}
|
||||||
|
|
||||||
|
func printTimetable(timetable map[models.Date]map[int]models.OfficeHour, slots []int) template.HTML {
|
||||||
|
var tableBody string
|
||||||
|
|
||||||
|
tableCell, _ := template.ParseFiles("templates/td.html")
|
||||||
|
for hour := 8; hour < 19; hour += 1 {
|
||||||
|
for minute := 0; minute < 60; minute += models.MinuteGranularity {
|
||||||
|
tableBody += "<tr>"
|
||||||
|
if minute == 0 {
|
||||||
|
tableBody += fmt.Sprintf("<td>%d Uhr</td>\n", hour)
|
||||||
|
} else {
|
||||||
|
tableBody += "<td></td>\n"
|
||||||
|
}
|
||||||
|
for day := 0; day < 5; day += 1 {
|
||||||
|
for slot := 0; slot < slots[day]; slot += 1 {
|
||||||
|
current, currentExists := timetable[models.Date{day, hour, minute}][slot]
|
||||||
|
|
||||||
|
if currentExists { // This slot is taken by some office hour
|
||||||
|
var continued bool = false // is this slot occupied by the same office hour the previous minute?
|
||||||
|
var predecessorExists bool
|
||||||
|
var predecessor models.OfficeHour
|
||||||
|
if hour > 0 && minute < models.MinuteGranularity {
|
||||||
|
predecessor, predecessorExists = timetable[models.Date{day, hour - 1, 60 - models.MinuteGranularity}][slot]
|
||||||
|
} else {
|
||||||
|
predecessor, predecessorExists = timetable[models.Date{day, hour, minute - models.MinuteGranularity}][slot]
|
||||||
|
}
|
||||||
|
if predecessorExists {
|
||||||
|
continued = (predecessor == current)
|
||||||
|
} else {
|
||||||
|
continued = false
|
||||||
|
}
|
||||||
|
if continued {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
var celldata bytes.Buffer
|
||||||
|
data := struct {
|
||||||
|
Rowspan int
|
||||||
|
StartHour int
|
||||||
|
StartMinute int
|
||||||
|
EndHour int
|
||||||
|
EndMinute int
|
||||||
|
CourseName string
|
||||||
|
TutorName string
|
||||||
|
RoomName string
|
||||||
|
}{current.Duration / models.MinuteGranularity,
|
||||||
|
current.Hour,
|
||||||
|
current.Minute,
|
||||||
|
current.Hour + ((current.Minute + current.Duration) / 60),
|
||||||
|
(current.Minute + current.Duration) % 60,
|
||||||
|
template.HTMLEscapeString(current.Course.Name),
|
||||||
|
current.Tutor.Name,
|
||||||
|
current.Room.Name,
|
||||||
|
}
|
||||||
|
tableCell.Execute(&celldata, data)
|
||||||
|
tableBody += celldata.String()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if slot+1 == slots[day] {
|
||||||
|
tableBody += "<td style=\"border-right: 1px dotted\"></td>\n"
|
||||||
|
} else {
|
||||||
|
tableBody += "<td></td>\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tableBody += "</tr>\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var table bytes.Buffer
|
||||||
|
tableTemplate, _ := template.ParseFiles("templates/officeHourTable.html")
|
||||||
|
|
||||||
|
tableData := struct {
|
||||||
|
ColspanMon int
|
||||||
|
ColspanTue int
|
||||||
|
ColspanWed int
|
||||||
|
ColspanThu int
|
||||||
|
ColspanFri int
|
||||||
|
TableBody template.HTML
|
||||||
|
}{
|
||||||
|
slots[0],
|
||||||
|
slots[1],
|
||||||
|
slots[2],
|
||||||
|
slots[3],
|
||||||
|
slots[4],
|
||||||
|
template.HTML(tableBody),
|
||||||
|
}
|
||||||
|
tableTemplate.Execute(&table, tableData)
|
||||||
|
return template.HTML(table.String())
|
||||||
|
}
|
15
course.go
15
course.go
|
@ -1,15 +0,0 @@
|
||||||
// course
|
|
||||||
package main
|
|
||||||
|
|
||||||
type Course struct {
|
|
||||||
Id int
|
|
||||||
Name string
|
|
||||||
Active bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCourses() []Course {
|
|
||||||
return []Course{
|
|
||||||
Course{1, "Dummyveranstaltung", true},
|
|
||||||
Course{2, "Dummyveranstaltung 2", true},
|
|
||||||
}
|
|
||||||
}
|
|
4
dummydatasqlite.sql
Normal file
4
dummydatasqlite.sql
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
INSERT INTO `room` (name, max_occupy) VALUES ('S2 15 345',2),('S2 15 415',1),('S2 15 336',2),('S2 15 444',1),('S2 15 333',1),('S2 14 420',1),('Sonstige',1024);
|
||||||
|
INSERT INTO `officeHour` VALUES (0,1,1,12,0,1,1,0,'',true,60),(1,1,1,12,15,2,1,0,'',true,60),(2,1,1,12,30,1,2,0,'',true,60);
|
||||||
|
INSERT INTO `tutor` (name, email) VALUES ('Dummyname','dummy@example.com');
|
||||||
|
INSERT INTO `course` (name) VALUES ('Integrationstheorie'),('Analysis II (engl.)'),('Analysis II'),('Mathe II für Informatik'),('Mathe II für Bauwesen'),('Diskrete Optimierung'),('Lineare Algebra II'),('Einführung in die Algebra'),('FGdI I&II'),('Algorithmic Discrete Mathematics'),('Einführung in die Stochastik'),('Mathe II für ET'),('Mathe II für Maschinenbau'),('Mathe IV für Maschinenbau'),('Num Mathe für MB (IV)'),('Höhere Mathematik II'),('Elementare PDE'),('LA für Physik und Lehramt'),('Analysis I'),('Mathe III ET'),('Mathe I für Informatik'),('Complex Analysis'),('Mathe & Statistik für Biologen'),('Mathe I für Maschinenbau'),('Mathe I für Bau'),('Nichtlineare Optimierung'),('Einführung in die Numerische Mathematik'),('Differentialgeometrie'),('Mathe I für ET'),('Mathe III (Bau)'),('W. Theorie'),('Gewöhnliche Differentialgleichungen'),('Geometrie für Lehramt'),('Mathe III MB'),('Statistik I für Humanwissenschaftler'),('Einführung in die Optimierung'),('Algebra'),('Lineare Algebra I'),('Höhere Mathematik 1'),('Darstellende Geometrie'),('Statistik 1 für WI'),('Diskrete Mathematik'),('Linear Algebra I (engl.)'),('Introduction to mathematical logic'),('Statistik I für WI'),('Weihnachtsknobelstraße'),('Numerische Lineare Algebra'),('Mathe IV (ET) / Mathe III (Inf) / Praktische Mathe (MEd)'),('Topologie'),('Linear Algebra II (engl.)'),('Einführung in die Finanzmathematik'),('Einführung in die mathematische Software'),('Mathematische Statistik'),('Algebraische Kurven'),('Analysis I (engl.)'),('Funktionalanalysis'),('Lebensversicherungsmathematik'),('Automaten, Formale Sprachen und Entscheidbarkeit (FGdI)'),('Mathematik für Chemiker'),('Numerik gewöhnlicher Differentialgleichungen'),('Darstellungstheorie'),('Aussagen- und Prädikatenlogik'),('Riemannsche Flächen'),('Mathematische Grundlagen der Quantenmechanik'),('Elementare Zahlentheorie'),('Einführung in die mathematische Modellierung'),('Stochastische Prozesse I'),('Mathematik im Kontext'),('Funktionalanalysis II'),('Mathematik IV (für ET) /Mathematik III (für Inf) /PraktischeMathematik (für M.Ed.Math)'),('Differentialgeometrie fuer VI'),('Probability Theory'),('Mathe für MINT'),('Mathematik als gemeinsame Sprache der Naturwissenschaften'),('Lineare Algebra I für Physiker'),('Manifolds'),('Kurvenschätzung'),('Spieltheorie'),('Einführung in die Programmierung'),('Algebraische Topologie'),('Schadenversicherungsmathematik'),('Partial Differential Equations I');
|
73
main.go
73
main.go
|
@ -1,68 +1,27 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"html/template"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"sprechstundentool/controllers"
|
||||||
|
"sprechstundentool/repositories"
|
||||||
|
"sprechstundentool/sqldb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func root(w http.ResponseWriter, req *http.Request) {
|
|
||||||
writeTimetablePage(w, req, template.HTML(""))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getByRoom(w http.ResponseWriter, req *http.Request) {
|
|
||||||
room, err := strconv.Atoi(req.FormValue("raum"))
|
|
||||||
if err != nil || room == 0 {
|
|
||||||
root(w, req)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
writeTimetablePage(w, req, printTimetable(getTimetable(getOfficeHoursByRoom(room))))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getByCourse(w http.ResponseWriter, req *http.Request) {
|
|
||||||
course, err := strconv.Atoi(req.FormValue("veranstaltung"))
|
|
||||||
if err != nil || course == 0 {
|
|
||||||
root(w, req)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
writeTimetablePage(w, req, printTimetable(getTimetable(getOfficeHoursByCourse(course))))
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeTimetablePage(w http.ResponseWriter, req *http.Request, timetable template.HTML) {
|
|
||||||
room, err := strconv.Atoi(req.FormValue("raum"))
|
|
||||||
if err != nil {
|
|
||||||
room = 0
|
|
||||||
}
|
|
||||||
course, err := strconv.Atoi(req.FormValue("veranstaltung"))
|
|
||||||
if err != nil {
|
|
||||||
course = 0
|
|
||||||
}
|
|
||||||
data := struct {
|
|
||||||
Courses []Course
|
|
||||||
Rooms []Room
|
|
||||||
Timetable template.HTML
|
|
||||||
SelectedRoom int
|
|
||||||
SelectedCourse int
|
|
||||||
}{getCourses(), getRooms(), timetable, room, course}
|
|
||||||
tmpl, err := template.ParseFiles("templates/index.html")
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
|
||||||
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error()))))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = tmpl.Execute(w, data)
|
|
||||||
if err != nil {
|
|
||||||
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error()))))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
http.HandleFunc("/getByRoom", getByRoom)
|
db := sqldb.ConnectDB()
|
||||||
http.HandleFunc("/getByCourse", getByCourse)
|
|
||||||
|
|
||||||
http.HandleFunc("/", root)
|
// Create repos
|
||||||
|
roomRepo := repositories.NewRoomRepo(db)
|
||||||
|
courseRepo := repositories.NewCourseRepo(db)
|
||||||
|
tutorRepo := repositories.NewTutorRepo(db)
|
||||||
|
officeHourRepo := repositories.NewOfficeHourRepo(db, roomRepo, tutorRepo, courseRepo)
|
||||||
|
|
||||||
|
h := controllers.NewBaseHandler(roomRepo, officeHourRepo, courseRepo, tutorRepo)
|
||||||
|
|
||||||
|
http.HandleFunc("/getByRoom", h.GetByRoomHandler)
|
||||||
|
http.HandleFunc("/getByCourse", h.GetByCourseHandler)
|
||||||
|
|
||||||
|
http.HandleFunc("/", h.RootHandler)
|
||||||
|
|
||||||
http.ListenAndServe(":8080", nil)
|
http.ListenAndServe(":8080", nil)
|
||||||
}
|
}
|
||||||
|
|
14
models/course.go
Normal file
14
models/course.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// course
|
||||||
|
package models
|
||||||
|
|
||||||
|
type Course struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CourseRepository interface {
|
||||||
|
FindByName(name string) (Course, error)
|
||||||
|
GetAll() ([]Course, error)
|
||||||
|
FindById(id int) (Course, error)
|
||||||
|
GetActive() ([]Course, error)
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
// date
|
// date
|
||||||
package main
|
package models
|
||||||
|
|
||||||
type Date struct {
|
type Date struct {
|
||||||
Day int
|
Day int
|
||||||
Hour int
|
Hour int
|
||||||
Minute int
|
Minute int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MinuteGranularity int = 5
|
23
models/officeHour.go
Normal file
23
models/officeHour.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// officeHour
|
||||||
|
package models
|
||||||
|
|
||||||
|
type OfficeHour struct {
|
||||||
|
Id int
|
||||||
|
Tutor Tutor
|
||||||
|
Week int
|
||||||
|
Date
|
||||||
|
Room Room
|
||||||
|
Course Course
|
||||||
|
Info string
|
||||||
|
Active bool
|
||||||
|
Duration int
|
||||||
|
}
|
||||||
|
|
||||||
|
type OfficeHourRepository interface {
|
||||||
|
FindById(id int) (OfficeHour, error)
|
||||||
|
FindByCourse(course Course) ([]OfficeHour, error)
|
||||||
|
FindByRoom(room Room) ([]OfficeHour, error)
|
||||||
|
GetAll() ([]OfficeHour, error)
|
||||||
|
Delete(officeHour OfficeHour) error
|
||||||
|
Add(officeHour OfficeHour) error
|
||||||
|
}
|
14
models/room.go
Normal file
14
models/room.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// raum
|
||||||
|
package models
|
||||||
|
|
||||||
|
type Room struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
MaxOccupy int
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoomRepository interface {
|
||||||
|
FindByName(name string) (Room, error)
|
||||||
|
GetAll() ([]Room, error)
|
||||||
|
FindById(id int) (Room, error)
|
||||||
|
}
|
15
models/tutor.go
Normal file
15
models/tutor.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// tutor
|
||||||
|
package models
|
||||||
|
|
||||||
|
type Tutor struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
Email string
|
||||||
|
}
|
||||||
|
|
||||||
|
type TutorRepository interface {
|
||||||
|
FindByEmail(Email string) ([]Tutor, error)
|
||||||
|
FindById(Id int) (Tutor, error)
|
||||||
|
GetAll() ([]Tutor, error)
|
||||||
|
Add(tutor Tutor) error
|
||||||
|
}
|
217
officeHour.go
217
officeHour.go
|
@ -1,217 +0,0 @@
|
||||||
// officeHour
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"html/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
const minuteGranularity int = 5
|
|
||||||
|
|
||||||
type OfficeHour struct {
|
|
||||||
Id int
|
|
||||||
Tutor Tutor
|
|
||||||
Week int
|
|
||||||
Date
|
|
||||||
Room Room
|
|
||||||
Course Course
|
|
||||||
Info string
|
|
||||||
Active bool
|
|
||||||
Duration int
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOfficeHours() []OfficeHour {
|
|
||||||
return []OfficeHour{
|
|
||||||
OfficeHour{
|
|
||||||
Id: 1,
|
|
||||||
Tutor: Tutor{1, "Dummy", "dummy@mathebau.de"},
|
|
||||||
Week: 0,
|
|
||||||
Date: Date{
|
|
||||||
Day: 0,
|
|
||||||
Hour: 12,
|
|
||||||
Minute: 0},
|
|
||||||
Room: getRooms()[0],
|
|
||||||
Course: getCourses()[0],
|
|
||||||
Info: "",
|
|
||||||
Active: true,
|
|
||||||
Duration: 60},
|
|
||||||
OfficeHour{
|
|
||||||
Id: 2,
|
|
||||||
Tutor: Tutor{1, "Dummy", "dummy@mathebau.de"},
|
|
||||||
Week: 0,
|
|
||||||
Date: Date{
|
|
||||||
Day: 0,
|
|
||||||
Hour: 13,
|
|
||||||
Minute: 30},
|
|
||||||
Room: getRooms()[0],
|
|
||||||
Course: getCourses()[1],
|
|
||||||
Info: "",
|
|
||||||
Active: true,
|
|
||||||
Duration: 90},
|
|
||||||
OfficeHour{
|
|
||||||
Id: 3,
|
|
||||||
Tutor: Tutor{1, "Dummy", "dummy@mathebau.de"},
|
|
||||||
Week: 0,
|
|
||||||
Date: Date{Day: 0,
|
|
||||||
Hour: 12,
|
|
||||||
Minute: 45},
|
|
||||||
Room: getRooms()[1],
|
|
||||||
Course: getCourses()[1],
|
|
||||||
Info: "",
|
|
||||||
Active: true,
|
|
||||||
Duration: 60}}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOfficeHoursByCourse(courseId int) []OfficeHour {
|
|
||||||
var result []OfficeHour
|
|
||||||
for _, option := range getOfficeHours() {
|
|
||||||
if option.Course.Id == courseId {
|
|
||||||
result = append(result, option)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOfficeHoursByRoom(roomId int) []OfficeHour {
|
|
||||||
var result []OfficeHour
|
|
||||||
for _, option := range getOfficeHours() {
|
|
||||||
if option.Room.Id == roomId {
|
|
||||||
result = append(result, option)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOfficeHourById(id int) OfficeHour {
|
|
||||||
return OfficeHour{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTimetable(officeHours []OfficeHour) (timetable map[Date]map[int]OfficeHour, slots []int) {
|
|
||||||
var fullTimetable = make(map[Date]map[int]OfficeHour)
|
|
||||||
for _, officeHour := range officeHours {
|
|
||||||
var slot int = 0
|
|
||||||
for minute := 0; minute < officeHour.Duration; minute += minuteGranularity { // find slot id
|
|
||||||
_, exists := fullTimetable[Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}]
|
|
||||||
if exists {
|
|
||||||
_, exists := fullTimetable[Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot]
|
|
||||||
if exists {
|
|
||||||
slot += 1
|
|
||||||
minute = 0
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fullTimetable[Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] = make(map[int]OfficeHour)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for minute := 0; minute < officeHour.Duration; minute += minuteGranularity { // write officeHour id to timetable
|
|
||||||
fullTimetable[Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] = officeHour
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slots = []int{1, 1, 1, 1, 1}
|
|
||||||
for date, _ := range fullTimetable {
|
|
||||||
if slots[date.Day] < len(fullTimetable[date]) {
|
|
||||||
slots[date.Day] = len(fullTimetable[date])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timetable = make(map[Date]map[int]OfficeHour)
|
|
||||||
for _, officeHour := range officeHours {
|
|
||||||
for slot := 0; slot < slots[officeHour.Date.Day]; slot += 1 {
|
|
||||||
if fullTimetable[officeHour.Date][slot] == officeHour {
|
|
||||||
timetable[officeHour.Date] = make(map[int]OfficeHour)
|
|
||||||
timetable[officeHour.Date][slot] = officeHour
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fullTimetable, slots
|
|
||||||
}
|
|
||||||
|
|
||||||
func printTimetable(timetable map[Date]map[int]OfficeHour, slots []int) template.HTML {
|
|
||||||
var tableBody string
|
|
||||||
|
|
||||||
tableCell, _ := template.ParseFiles("templates/td.html")
|
|
||||||
for hour := 8; hour < 19; hour += 1 {
|
|
||||||
for minute := 0; minute < 60; minute += minuteGranularity {
|
|
||||||
tableBody += "<tr>"
|
|
||||||
if minute == 0 {
|
|
||||||
tableBody += fmt.Sprintf("<td>%d Uhr</td>\n", hour)
|
|
||||||
} else {
|
|
||||||
tableBody += "<td></td>\n"
|
|
||||||
}
|
|
||||||
for day := 0; day < 5; day += 1 {
|
|
||||||
for slot := 0; slot < slots[day]; slot += 1 {
|
|
||||||
current, currentExists := timetable[Date{day, hour, minute}][slot]
|
|
||||||
|
|
||||||
if currentExists { // This slot is taken by some office hour
|
|
||||||
var continued bool = false // is this slot occupied by the same office hour the previous minute?
|
|
||||||
var predecessorExists bool
|
|
||||||
var predecessor OfficeHour
|
|
||||||
if hour > 0 && minute < minuteGranularity {
|
|
||||||
predecessor, predecessorExists = timetable[Date{day, hour - 1, 60 - minuteGranularity}][slot]
|
|
||||||
} else {
|
|
||||||
predecessor, predecessorExists = timetable[Date{day, hour, minute - minuteGranularity}][slot]
|
|
||||||
}
|
|
||||||
if predecessorExists {
|
|
||||||
continued = (predecessor == current)
|
|
||||||
} else {
|
|
||||||
continued = false
|
|
||||||
}
|
|
||||||
if continued {
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
var celldata bytes.Buffer
|
|
||||||
data := struct {
|
|
||||||
Rowspan int
|
|
||||||
StartHour int
|
|
||||||
StartMinute int
|
|
||||||
EndHour int
|
|
||||||
EndMinute int
|
|
||||||
CourseName string
|
|
||||||
TutorName string
|
|
||||||
RoomName string
|
|
||||||
}{current.Duration / minuteGranularity,
|
|
||||||
current.Hour,
|
|
||||||
current.Minute,
|
|
||||||
current.Hour + ((current.Minute + current.Duration) / 60),
|
|
||||||
(current.Minute + current.Duration) % 60,
|
|
||||||
template.HTMLEscapeString(current.Course.Name),
|
|
||||||
current.Tutor.Name,
|
|
||||||
current.Room.Name,
|
|
||||||
}
|
|
||||||
tableCell.Execute(&celldata, data)
|
|
||||||
tableBody += celldata.String()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if slot+1 == slots[day] {
|
|
||||||
tableBody += "<td style=\"border-right: 1px dotted\"></td>\n"
|
|
||||||
} else {
|
|
||||||
tableBody += "<td></td>\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tableBody += "</tr>\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var table bytes.Buffer
|
|
||||||
tableTemplate, _ := template.ParseFiles("templates/officeHourTable.html")
|
|
||||||
|
|
||||||
tableData := struct {
|
|
||||||
ColspanMon int
|
|
||||||
ColspanTue int
|
|
||||||
ColspanWed int
|
|
||||||
ColspanThu int
|
|
||||||
ColspanFri int
|
|
||||||
TableBody template.HTML
|
|
||||||
}{
|
|
||||||
slots[0],
|
|
||||||
slots[1],
|
|
||||||
slots[2],
|
|
||||||
slots[3],
|
|
||||||
slots[4],
|
|
||||||
template.HTML(tableBody),
|
|
||||||
}
|
|
||||||
tableTemplate.Execute(&table, tableData)
|
|
||||||
return template.HTML(table.String())
|
|
||||||
}
|
|
67
repositories/course.go
Normal file
67
repositories/course.go
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// course
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"sprechstundentool/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CourseRepo struct {
|
||||||
|
db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCourseRepo(db *sql.DB) *CourseRepo {
|
||||||
|
return &CourseRepo{
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CourseRepo) FindByName(name string) (models.Course, error) {
|
||||||
|
row := r.db.QueryRow("SELECT * FROM course WHERE name=?", name)
|
||||||
|
var course models.Course
|
||||||
|
if err := row.Scan(&course.Id, &course.Name); err != nil {
|
||||||
|
return models.Course{}, err
|
||||||
|
}
|
||||||
|
return course, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CourseRepo) FindById(id int) (models.Course, error) {
|
||||||
|
row := r.db.QueryRow("SELECT * FROM course WHERE id=?", id)
|
||||||
|
var course models.Course
|
||||||
|
if err := row.Scan(&course.Id, &course.Name); err != nil {
|
||||||
|
return models.Course{}, err
|
||||||
|
}
|
||||||
|
return course, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CourseRepo) GetAll() ([]models.Course, error) {
|
||||||
|
rows, err := r.db.Query("SELECT * FROM course")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
return r.getFromRows(rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CourseRepo) GetActive() ([]models.Course, error) {
|
||||||
|
rows, err := r.db.Query("SELECT * FROM course WHERE active")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
return r.getFromRows(rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CourseRepo) getFromRows(rows *sql.Rows) ([]models.Course, error) {
|
||||||
|
var courses []models.Course
|
||||||
|
for rows.Next() {
|
||||||
|
var course models.Course
|
||||||
|
if err := rows.Scan(&course.Id, &course.Name); err != nil {
|
||||||
|
return courses, err
|
||||||
|
}
|
||||||
|
courses = append(courses, course)
|
||||||
|
}
|
||||||
|
return courses, nil
|
||||||
|
}
|
95
repositories/officeHour.go
Normal file
95
repositories/officeHour.go
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
// officeHour
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"sprechstundentool/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OfficeHourRepo struct {
|
||||||
|
db *sql.DB
|
||||||
|
roomRepo *RoomRepo
|
||||||
|
tutorRepo *TutorRepo
|
||||||
|
courseRepo *CourseRepo
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOfficeHourRepo(db *sql.DB, roomRepo *RoomRepo, tutorRepo *TutorRepo, courseRepo *CourseRepo) *OfficeHourRepo {
|
||||||
|
return &OfficeHourRepo{
|
||||||
|
db: db,
|
||||||
|
roomRepo: roomRepo,
|
||||||
|
tutorRepo: tutorRepo,
|
||||||
|
courseRepo: courseRepo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OfficeHourRepo) GetAll() ([]models.OfficeHour, error) {
|
||||||
|
rows, err := r.db.Query("SELECT * FROM officeHour")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
return r.getFromRows(rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OfficeHourRepo) FindByCourse(course models.Course) ([]models.OfficeHour, error) {
|
||||||
|
rows, err := r.db.Query("SELECT * FROM officeHour WHERE course=?", course.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
return r.getFromRows(rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OfficeHourRepo) FindByRoom(room models.Room) ([]models.OfficeHour, error) {
|
||||||
|
rows, err := r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
return r.getFromRows(rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OfficeHourRepo) FindById(id int) (models.OfficeHour, error) {
|
||||||
|
return r.getFromRow(r.db.QueryRow("SELECT * FROM officeHour WHERE id=?", id))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OfficeHourRepo) Delete(officeHour models.OfficeHour) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OfficeHourRepo) getFromRow(row *sql.Row) (models.OfficeHour, error) {
|
||||||
|
var officeHour models.OfficeHour
|
||||||
|
var day, hour, minute, tutorid int
|
||||||
|
var roomName, courseName string
|
||||||
|
err := row.Scan(&officeHour.Id, &tutorid, &day, &hour, &minute, &roomName, &courseName, &officeHour.Week, &officeHour.Info, &officeHour.Active, &officeHour.Duration)
|
||||||
|
if err != nil {
|
||||||
|
return models.OfficeHour{}, err
|
||||||
|
}
|
||||||
|
officeHour.Date = models.Date{day, hour, minute}
|
||||||
|
officeHour.Room, _ = r.roomRepo.FindByName(roomName)
|
||||||
|
officeHour.Tutor, _ = r.tutorRepo.FindById(tutorid)
|
||||||
|
officeHour.Course, _ = r.courseRepo.FindByName(courseName)
|
||||||
|
return officeHour, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *OfficeHourRepo) getFromRows(rows *sql.Rows) ([]models.OfficeHour, error) {
|
||||||
|
var officeHours []models.OfficeHour
|
||||||
|
for rows.Next() {
|
||||||
|
var officeHour models.OfficeHour
|
||||||
|
var day, hour, minute, tutorId, roomId, courseId int
|
||||||
|
if err := rows.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &courseId, &officeHour.Week, &officeHour.Info, &officeHour.Active, &officeHour.Duration); err != nil {
|
||||||
|
return officeHours, err
|
||||||
|
}
|
||||||
|
officeHour.Date = models.Date{day, hour, minute}
|
||||||
|
officeHour.Room, _ = r.roomRepo.FindById(roomId)
|
||||||
|
officeHour.Tutor, _ = r.tutorRepo.FindById(tutorId)
|
||||||
|
officeHour.Course, _ = r.courseRepo.FindById(courseId)
|
||||||
|
officeHours = append(officeHours, officeHour)
|
||||||
|
}
|
||||||
|
return officeHours, nil
|
||||||
|
}
|
59
repositories/room.go
Normal file
59
repositories/room.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// raum
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"sprechstundentool/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoomRepo struct {
|
||||||
|
db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoomRepo(db *sql.DB) *RoomRepo {
|
||||||
|
return &RoomRepo{
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RoomRepo) FindByName(name string) (models.Room, error) {
|
||||||
|
row := r.db.QueryRow("SELECT * FROM room WHERE name=?", name)
|
||||||
|
var room models.Room
|
||||||
|
if err := row.Scan(&room.Name, &room.MaxOccupy); err != nil {
|
||||||
|
return models.Room{}, err
|
||||||
|
}
|
||||||
|
return room, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RoomRepo) FindById(id int) (models.Room, error) {
|
||||||
|
row := r.db.QueryRow("SELECT * FROM room WHERE id=?", id)
|
||||||
|
var room models.Room
|
||||||
|
if err := row.Scan(&room.Id, &room.Name, &room.MaxOccupy); err != nil {
|
||||||
|
return models.Room{}, err
|
||||||
|
}
|
||||||
|
return room, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RoomRepo) GetAll() ([]models.Room, error) {
|
||||||
|
rows, err := r.db.Query("SELECT * FROM room")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var rooms []models.Room
|
||||||
|
for rows.Next() {
|
||||||
|
var room models.Room
|
||||||
|
if err := rows.Scan(&room.Id, &room.Name, &room.MaxOccupy); err != nil {
|
||||||
|
return rooms, err
|
||||||
|
}
|
||||||
|
rooms = append(rooms, room)
|
||||||
|
}
|
||||||
|
return rooms, nil
|
||||||
|
}
|
||||||
|
func (r *RoomRepo) Save(room models.Room) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (r *RoomRepo) Add(room models.Room) error {
|
||||||
|
return nil
|
||||||
|
}
|
68
repositories/tutor.go
Normal file
68
repositories/tutor.go
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// tutor
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"sprechstundentool/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TutorRepo struct {
|
||||||
|
db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTutorRepo(db *sql.DB) *TutorRepo {
|
||||||
|
return &TutorRepo{
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *TutorRepo) FindByEmail(email string) ([]models.Tutor, error) {
|
||||||
|
rows, err := r.db.Query("SELECT * FROM tutor WHERE email=?", email)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var tutors []models.Tutor
|
||||||
|
for rows.Next() {
|
||||||
|
var tutor models.Tutor
|
||||||
|
if err := rows.Scan(&tutor.Id, &tutor.Name, &tutor.Email); err != nil {
|
||||||
|
return tutors, err
|
||||||
|
}
|
||||||
|
tutors = append(tutors, tutor)
|
||||||
|
}
|
||||||
|
return tutors, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *TutorRepo) FindById(id int) (models.Tutor, error) {
|
||||||
|
row := r.db.QueryRow("SELECT * FROM tutor WHERE id=?", id)
|
||||||
|
var tutor models.Tutor
|
||||||
|
if err := row.Scan(&tutor.Id, &tutor.Name, &tutor.Email); err != nil {
|
||||||
|
return models.Tutor{}, err
|
||||||
|
}
|
||||||
|
return tutor, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *TutorRepo) GetAll() ([]models.Tutor, error) {
|
||||||
|
rows, err := r.db.Query("SELECT * FROM tutor")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var tutors []models.Tutor
|
||||||
|
for rows.Next() {
|
||||||
|
var tutor models.Tutor
|
||||||
|
if err := rows.Scan(&tutor.Id, &tutor.Name, &tutor.Email); err != nil {
|
||||||
|
return tutors, err
|
||||||
|
}
|
||||||
|
tutors = append(tutors, tutor)
|
||||||
|
}
|
||||||
|
return tutors, nil
|
||||||
|
}
|
||||||
|
func (r *TutorRepo) Save(tutor models.Tutor) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (r *TutorRepo) Add(tutor models.Tutor) error {
|
||||||
|
return nil
|
||||||
|
}
|
20
room.go
20
room.go
|
@ -1,20 +0,0 @@
|
||||||
// raum
|
|
||||||
package main
|
|
||||||
|
|
||||||
type Room struct {
|
|
||||||
Id int
|
|
||||||
Name string
|
|
||||||
Max_occupy int
|
|
||||||
Active bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRooms() []Room {
|
|
||||||
return []Room{
|
|
||||||
Room{1, "S2 15 345", 2, true},
|
|
||||||
Room{2, "S2 15 415", 1, true},
|
|
||||||
Room{3, "S2 15 336", 2, true},
|
|
||||||
Room{4, "S2 15 444", 1, true},
|
|
||||||
Room{5, "S2 15 333", 1, true},
|
|
||||||
Room{6, "S2 14 420", 1, false},
|
|
||||||
Room{7, "Sonstige", 255, true}}
|
|
||||||
}
|
|
17
sqldb/sqldb.go
Normal file
17
sqldb/sqldb.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package sqldb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConnectDB opens a connection to the database
|
||||||
|
func ConnectDB() *sql.DB {
|
||||||
|
db, err := sql.Open("sqlite3", "sprechstunden.db")
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return db
|
||||||
|
}
|
62
sqlite.sql
Normal file
62
sqlite.sql
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
--
|
||||||
|
-- Table structure for table `room`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `room`;
|
||||||
|
CREATE TABLE `room` (
|
||||||
|
`id` INTEGER PRIMARY KEY,
|
||||||
|
`name` text NOT NULL,
|
||||||
|
`max_occupy` int DEFAULT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `request`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `request`;
|
||||||
|
CREATE TABLE `request` (
|
||||||
|
`id` INTEGER PRIMARY KEY,
|
||||||
|
`officeHour` int DEFAULT NULL,
|
||||||
|
`type` int DEFAULT NULL,
|
||||||
|
`code` text DEFAULT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `officeHour`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `officeHour`;
|
||||||
|
CREATE TABLE `officeHour` (
|
||||||
|
`id` INTEGER PRIMARY KEY,
|
||||||
|
`tutor` int DEFAULT NULL,
|
||||||
|
`day` int DEFAULT NULL,
|
||||||
|
`hour` int DEFAULT NULL,
|
||||||
|
`minute` int DEFAULT NULL,
|
||||||
|
`room` int DEFAULT NULL,
|
||||||
|
`course` int DEFAULT NULL,
|
||||||
|
`week` int DEFAULT NULL,
|
||||||
|
`info` text DEFAULT NULL,
|
||||||
|
`active` bool DEFAULT NULL,
|
||||||
|
`duration` int DEFAULT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `tutor`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `tutor`;
|
||||||
|
CREATE TABLE `tutor` (
|
||||||
|
`id` INTEGER PRIMARY KEY,
|
||||||
|
`name` tinytext DEFAULT NULL,
|
||||||
|
`email` tinytext DEFAULT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `course`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `course`;
|
||||||
|
CREATE TABLE `course` (
|
||||||
|
`id` INTEGER PRIMARY KEY,
|
||||||
|
`name` varchar(255) DEFAULT NULL
|
||||||
|
);
|
|
@ -6,7 +6,7 @@
|
||||||
<form method="GET" action="/getByCourse">
|
<form method="GET" action="/getByCourse">
|
||||||
<label for="veranstaltung">Veranstaltung: </label>
|
<label for="veranstaltung">Veranstaltung: </label>
|
||||||
<select name="veranstaltung" size="1" onchange="document.forms[0].submit()">
|
<select name="veranstaltung" size="1" onchange="document.forms[0].submit()">
|
||||||
<option value="0">Alle</option>
|
<option value="">Alle</option>
|
||||||
{{range $course := .Courses}}
|
{{range $course := .Courses}}
|
||||||
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>{{end}}
|
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>{{end}}
|
||||||
</select>
|
</select>
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
<form method="GET" action="/getByRoom">
|
<form method="GET" action="/getByRoom">
|
||||||
<label for="raum">Raum: </label>
|
<label for="raum">Raum: </label>
|
||||||
<select name="raum" size="1" onchange="document.forms[1].submit()">
|
<select name="raum" size="1" onchange="document.forms[1].submit()">
|
||||||
<option value="0">Alle</option>
|
<option value="">Alle</option>
|
||||||
{{range $room := .Rooms}}
|
{{range $room := .Rooms}}
|
||||||
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>{{end}}
|
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>{{end}}
|
||||||
</select>
|
</select>
|
||||||
|
|
8
tutor.go
8
tutor.go
|
@ -1,8 +0,0 @@
|
||||||
// tutor
|
|
||||||
package main
|
|
||||||
|
|
||||||
type Tutor struct {
|
|
||||||
Id int
|
|
||||||
Name string
|
|
||||||
Email string
|
|
||||||
}
|
|
Loading…
Reference in a new issue