changed names of database columns

This commit is contained in:
z1glr
2025-01-23 10:12:12 +00:00
parent 7265a4e36a
commit c752bc6c14
36 changed files with 604 additions and 605 deletions

View File

@@ -1,22 +0,0 @@
package assignments
import (
"github.com/johannesbuehl/golunteer/backend/pkg/db"
)
type EventAssignment struct {
TaskID int `db:"taskID" json:"taskID"`
TaskName string `db:"taskName" json:"taskName"`
UserName *string `db:"userName" json:"userName"`
}
func Event(eventID int) ([]EventAssignment, error) {
// get the assignments from the database
var assignmentRows []EventAssignment
if err := db.DB.Select(&assignmentRows, "SELECT USERS.name AS userName, taskID, TASKS.name AS taskName FROM USER_ASSIGNMENTS LEFT JOIN USERS ON USER_ASSIGNMENTS.userName = USERS.name LEFT JOIN TASKS ON USER_ASSIGNMENTS.taskID = TASKS.id WHERE USER_ASSIGNMENTS.eventID = ?", eventID); err != nil {
return nil, err
} else {
return assignmentRows, nil
}
}

View File

@@ -5,24 +5,24 @@ import (
)
type AvailabilityDB struct {
Id int `db:"id" json:"id" validate:"required"`
Availability `validate:"required"`
AvailabilityID int `db:"availabilityID" json:"availabilityID" validate:"required"`
Availability `validate:"required"`
}
type Availability struct {
Name string `db:"name" json:"name" validate:"required"`
Enabled bool `db:"enabled" json:"enabled" validate:"required"`
Color string `db:"color" json:"color" validate:"required"`
AvailabilityName string `db:"availabilityName" json:"availabilityName" validate:"required"`
Enabled bool `db:"enabled" json:"enabled"`
Color string `db:"color" json:"color" validate:"required"`
}
func Add(a Availability) error {
_, err := db.DB.NamedExec("INSERT INTO AVAILABILITIES (name, color, enabled) VALUES (:name, :color, :enabled)", a)
_, err := db.DB.NamedExec("INSERT INTO AVAILABILITIES (availabilityName, color, enabled) VALUES (:availabilityName, :color, :enabled)", a)
return err
}
func Update(a AvailabilityDB) error {
_, err := db.DB.NamedExec("UPDATE AVAILABILITIES SET name = :name, color = :color, enabled = :enabled WHERE id = :id", a)
_, err := db.DB.NamedExec("UPDATE AVAILABILITIES SET availabilityName = :availabilityName, color = :color, enabled = :enabled WHERE availabilityID = :availabilityID", a)
return err
}
@@ -46,10 +46,10 @@ func Keys() (map[int]Availability, error) {
availabilities := map[int]Availability{}
for _, a := range availabilitiesRaw {
availabilities[a.Id] = Availability{
Name: a.Name,
Enabled: a.Enabled,
Color: a.Color,
availabilities[a.AvailabilityID] = Availability{
AvailabilityName: a.AvailabilityName,
Enabled: a.Enabled,
Color: a.Color,
}
}
@@ -58,7 +58,7 @@ func Keys() (map[int]Availability, error) {
}
func Delete(id int) error {
_, err := db.DB.Exec("DELETE FROM AVAILABILITIES WHERE id = $1", id)
_, err := db.DB.Exec("DELETE FROM AVAILABILITIES WHERE availabilityID = $1", id)
return err
}

View File

@@ -24,7 +24,7 @@ func Event(eventID int) (map[string]string, error) {
return nil, err
} else {
for _, a := range availabilitiesRows {
eventAvailabilities[a.UserName] = availabilitiesMap[a.AvailabilityID].Name
eventAvailabilities[a.UserName] = availabilitiesMap[a.AvailabilityID].AvailabilityName
}
return eventAvailabilities, nil

View File

@@ -31,7 +31,7 @@ func init() {
var admin struct {
Admin bool `db:"admin"`
}
if err := DB.QueryRowx("SELECT admin FROM USERS WHERE name = 'admin'").StructScan(&admin); err != nil {
if err := DB.QueryRowx("SELECT admin FROM USERS WHERE userName = 'admin'").StructScan(&admin); err != nil {
// if the error isn't because there was no result, it's a real one
if err != sql.ErrNoRows {
panic(fmt.Errorf("can't query for the admin-user: %v", err))

View File

@@ -4,14 +4,30 @@ import (
"slices"
"github.com/johannesbuehl/golunteer/backend/pkg/db"
"github.com/johannesbuehl/golunteer/backend/pkg/db/assignments"
"github.com/johannesbuehl/golunteer/backend/pkg/db/availabilities"
"github.com/johannesbuehl/golunteer/backend/pkg/logger"
)
type EventData struct {
EventID int `db:"eventID" json:"eventID" validate:"required"`
Date string `db:"date" json:"date" validate:"required"`
Description string `db:"description" json:"description"`
}
type EventPatch struct {
EventData
Tasks []int `json:"tasks" validate:"required,min=1"`
}
type EventAssignment struct {
TaskID int `db:"taskID" json:"taskID"`
TaskName string `db:"taskName" json:"taskName"`
UserName *string `db:"userName" json:"userName"`
}
type EventWithAssignment struct {
eventDataDB
Tasks []assignments.EventAssignment `json:"tasks"`
EventData
Tasks []EventAssignment `json:"tasks"`
}
type EventWithAvailabilities struct {
@@ -19,32 +35,32 @@ type EventWithAvailabilities struct {
Availabilities map[string]string `json:"availabilities"`
}
type eventDataDB struct {
ID int `db:"id" json:"id" validate:"required"`
Date string `db:"date" json:"date" validate:"required"`
type EventCreate struct {
Date string `db:"date" json:"date" validate:"required,datetime=2006-01-02T15:04:05.999999999Z"`
Description string `db:"description" json:"description"`
Tasks []int `json:"tasks" validate:"required,min=1"`
}
// transform the database-entry to an Event
func (e eventDataDB) Event() (EventWithAssignment, error) {
func (e EventData) Event() (EventWithAssignment, error) {
// get the assignments associated with the event
if assignemnts, err := assignments.Event(e.ID); err != nil {
if assignemnts, err := Assignments(e.EventID); err != nil {
return EventWithAssignment{}, err
} else {
return EventWithAssignment{
eventDataDB: e,
Tasks: assignemnts,
EventData: e,
Tasks: assignemnts,
}, nil
}
}
func (e eventDataDB) EventWithAvailabilities() (EventWithAvailabilities, error) {
func (e EventData) EventWithAvailabilities() (EventWithAvailabilities, error) {
// get the event with assignments
if event, err := e.Event(); err != nil {
return EventWithAvailabilities{}, err
// get the availabilities
} else if availabilities, err := availabilities.Event(e.ID); err != nil {
} else if availabilities, err := availabilities.Event(e.EventID); err != nil {
return EventWithAvailabilities{}, err
} else {
return EventWithAvailabilities{
@@ -54,12 +70,6 @@ func (e eventDataDB) EventWithAvailabilities() (EventWithAvailabilities, error)
}
}
type EventCreate struct {
Date string `db:"date" json:"date" validate:"required,datetime=2006-01-02T15:04:05.999999999Z"`
Description string `db:"description" json:"description"`
Tasks []int `json:"tasks" validate:"required,min=1"`
}
func Create(event EventCreate) error {
// convert the date to utc
if result, err := db.DB.NamedExec("INSERT INTO EVENTS (date, description) VALUES (:date, :description)", event); err != nil {
@@ -86,7 +96,7 @@ func Create(event EventCreate) error {
// create the assignments
if _, err := db.DB.NamedExec("INSERT INTO USER_ASSIGNMENTS (eventID, taskID) VALUES (:eventID, :taskID)", tasks); err != nil {
// delete the event again
db.DB.Query("DELETE FROM EVENTS WHERE id = ?", id)
db.DB.Query("DELETE FROM EVENTS WHERE eventID = ?", id)
return err
}
@@ -95,25 +105,20 @@ func Create(event EventCreate) error {
return nil
}
type EventPatch struct {
eventDataDB
Tasks []int `json:"tasks" validate:"required,min=1"`
}
func Update(event EventPatch) error {
// update the event itself
if _, err := db.DB.NamedExec("UPDATE EVENTS SET description = :description, date = :date WHERE id = :id", event); err != nil {
if _, err := db.DB.NamedExec("UPDATE EVENTS SET description = :description, date = :date WHERE eventID = :id", event); err != nil {
return err
// get the tasks currently assigned to the event
} else {
type TaskID struct {
ID int `db:"taskID"`
TaskID int `db:"taskID"`
}
var taskRows []TaskID
if err := db.DB.Select(&taskRows, "SELECT taskID FROM USER_ASSIGNMENTS WHERE eventID = ?", event.ID); err != nil {
if err := db.DB.Select(&taskRows, "SELECT taskID FROM USER_ASSIGNMENTS WHERE eventID = $1", event.EventID); err != nil {
return err
} else {
type Task struct {
@@ -125,17 +130,17 @@ func Update(event EventPatch) error {
deleteRows := []Task{}
for _, row := range taskRows {
if !slices.Contains(event.Tasks, row.ID) {
deleteRows = append(deleteRows, Task{TaskID: row, EventID: event.ID})
if !slices.Contains(event.Tasks, row.TaskID) {
deleteRows = append(deleteRows, Task{TaskID: row, EventID: event.EventID})
}
}
// extract the rows that need to be created
createRows := []Task{}
for _, id := range event.Tasks {
if !slices.Contains(taskRows, TaskID{ID: id}) {
createRows = append(createRows, Task{TaskID: TaskID{ID: id}, EventID: event.ID})
for _, taskID := range event.Tasks {
if !slices.Contains(taskRows, TaskID{TaskID: taskID}) {
createRows = append(createRows, Task{TaskID: TaskID{TaskID: taskID}, EventID: event.EventID})
}
}
@@ -158,8 +163,8 @@ func Update(event EventPatch) error {
}
}
func All() ([]eventDataDB, error) {
var dbRows []eventDataDB
func All() ([]EventData, error) {
var dbRows []EventData
if err := db.DB.Select(&dbRows, "SELECT * FROM EVENTS"); err != nil {
return nil, err
@@ -177,7 +182,7 @@ func WithAssignments() ([]EventWithAssignment, error) {
for ii, e := range eventsDB {
if ev, err := e.Event(); err != nil {
logger.Logger.Error().Msgf("can't get assignments for event with id = %d: %v", e.ID, err)
logger.Logger.Error().Msgf("can't get assignments for event with assignmentID = %d: %v", e.EventID, err)
} else {
events[ii] = ev
}
@@ -196,7 +201,7 @@ func WithAvailabilities() ([]EventWithAvailabilities, error) {
for ii, e := range eventsDB {
if ev, err := e.EventWithAvailabilities(); err != nil {
logger.Logger.Error().Msgf("can't get availabilities for event with id = %d: %v", e.ID, err)
logger.Logger.Error().Msgf("can't get availabilities for event with eventID = %d: %v", e.EventID, err)
} else {
events[ii] = ev
}
@@ -206,12 +211,22 @@ func WithAvailabilities() ([]EventWithAvailabilities, error) {
}
}
func UserPending(userName string) (int, error) {
func UserPending(userName string) ([]EventData, error) {
var result []EventData
if err := db.DB.Select(&result, "SELECT eventID, date, description FROM EVENTS WHERE NOT EXISTS (SELECT 1 FROM USER_AVAILABILITIES WHERE USER_AVAILABILITIES.eventID = EVENTS.eventID AND USER_AVAILABILITIES.userName = ?)", userName); err != nil {
return nil, err
} else {
return result, nil
}
}
func UserPendingCount(userName string) (int, error) {
var result struct {
Count int `db:"count(*)"`
}
if err := db.DB.QueryRowx("SELECT count(*) FROM EVENTS WHERE NOT EXISTS (SELECT 1 FROM USER_AVAILABILITIES WHERE USER_AVAILABILITIES.eventID = EVENTS.id AND USER_AVAILABILITIES.userName = ?)", userName).StructScan(&result); err != nil {
if err := db.DB.QueryRowx("SELECT count(*) FROM EVENTS WHERE NOT EXISTS (SELECT 1 FROM USER_AVAILABILITIES WHERE USER_AVAILABILITIES.eventID = EVENTS.eventID AND USER_AVAILABILITIES.userName = ?)", userName).StructScan(&result); err != nil {
return 0, err
} else {
return result.Count, nil
@@ -219,7 +234,35 @@ func UserPending(userName string) (int, error) {
}
func Delete(eventId int) error {
_, err := db.DB.Exec("DELETE FROM EVENTS WHERE id = ?", eventId)
_, err := db.DB.Exec("DELETE FROM EVENTS WHERE eventID = ?", eventId)
return err
}
func Assignments(eventID int) ([]EventAssignment, error) {
// get the assignments from the database
var assignmentRows []EventAssignment
if err := db.DB.Select(&assignmentRows, "SELECT USERS.userName, TASKS.taskID, TASKS.taskName FROM USER_ASSIGNMENTS LEFT JOIN USERS ON USER_ASSIGNMENTS.userName = USERS.userName LEFT JOIN TASKS ON USER_ASSIGNMENTS.taskID = TASKS.taskID WHERE USER_ASSIGNMENTS.eventID = ?", eventID); err != nil {
return nil, err
} else {
return assignmentRows, nil
}
}
func User(userName string) ([]EventWithAssignment, error) {
// get all assignments of the user
// var events []EventWithAssignment
var events []struct {
EventData
TaskID int `db:"taskID"`
UserName string `db:"userName"`
}
if err := db.DB.Select(&events, "SELECT DISTINCT * FROM USER_ASSIGNMENTS INNER JOIN EVENTS ON USER_ASSIGNMENTS.eventID = EVENTS.eventID WHERE userName = $1", userName); err != nil {
return nil, err
} else {
return nil, nil
}
}

View File

@@ -38,17 +38,17 @@ func setup() {
// create an admin-user
user := struct {
Name string `db:"name"`
UserName string `db:"userName"`
Password []byte `db:"password"`
Admin bool `db:"admin"`
TokenID string `db:"tokenID"`
}{
Name: "admin",
UserName: "admin",
Password: passwordHash,
Admin: true,
TokenID: uuid.NewString(),
}
if _, err := DB.NamedExec("INSERT INTO USERS (name, password, tokenID, admin) VALUES (:name, :password, :tokenID, :admin)", &user); err != nil {
if _, err := DB.NamedExec("INSERT INTO USERS (userName, password, tokenID, admin) VALUES (:userName, :password, :tokenID, :admin)", &user); err != nil {
panic(fmt.Errorf("can't insert admin-user into the database: %v", err))
}

View File

@@ -5,13 +5,13 @@ import (
)
type TaskDB struct {
ID int `json:"id" db:"id" validate:"required"`
Task `valdate:"required" `
TaskID int `json:"taskID" db:"taskID" validate:"required"`
Task `valdate:"required" `
}
type Task struct {
Name string `json:"name" db:"name" validate:"required"`
Enabled bool `json:"enabled" db:"enabled" validate:"required"`
TaskName string `json:"taskName" db:"taskName" validate:"required"`
Enabled bool `json:"enabled" db:"enabled" validate:"required"`
}
func GetSlice() ([]TaskDB, error) {
@@ -33,9 +33,9 @@ func GetMap() (map[int]Task, error) {
tasks := map[int]Task{}
for _, a := range tasksRaw {
tasks[a.ID] = Task{
Name: a.Name,
Enabled: a.Enabled,
tasks[a.TaskID] = Task{
TaskName: a.TaskName,
Enabled: a.Enabled,
}
}
@@ -44,19 +44,19 @@ func GetMap() (map[int]Task, error) {
}
func Add(t Task) error {
_, err := db.DB.NamedExec("INSERT INTO TASKS (name, enabled) VALUES (:name, :enabled)", &t)
_, err := db.DB.NamedExec("INSERT INTO TASKS (taskName, enabled) VALUES (:taskName, :enabled)", &t)
return err
}
func Update(t TaskDB) error {
_, err := db.DB.NamedExec("UPDATE TASKS set name = :name, enabled = :enabled WHERE id = :id", &t)
_, err := db.DB.NamedExec("UPDATE TASKS set taskName = :taskName, enabled = :enabled WHERE taskID = :taskID", &t)
return err
}
func Delete(i int) error {
_, err := db.DB.Exec("DELETE FROM TASKS WHERE id = $1", i)
_, err := db.DB.Exec("DELETE FROM TASKS WHERE taskID = $1", i)
return err
}

View File

@@ -7,8 +7,8 @@ import (
)
type User struct {
Name string `db:"name" json:"userName"`
Admin bool `db:"admin" json:"admin"`
UserName string `db:"userName" json:"userName"`
Admin bool `db:"admin" json:"admin"`
}
type UserChangePassword struct {
@@ -25,7 +25,7 @@ func Get() ([]User, error) {
// get the users from the database
var users []User
if err := db.DB.Select(&users, "SELECT name, admin FROM USERS"); err != nil {
if err := db.DB.Select(&users, "SELECT userName, admin FROM USERS"); err != nil {
return nil, err
} else {
return users, nil
@@ -37,7 +37,7 @@ func TokenID(userName string) (string, error) {
TokenID string `db:"tokenID"`
}
err := db.DB.Get(&dbResult, "SELECT tokenID FROM USERS WHERE name = ?", userName)
err := db.DB.Get(&dbResult, "SELECT tokenID FROM USERS WHERE userName = ?", userName)
return dbResult.TokenID, err
}
@@ -63,7 +63,7 @@ func Add(user UserAdd) error {
TokenID: uuid.NewString(),
}
_, err := db.DB.NamedExec("INSERT INTO USERS (name, password, admin, tokenID) VALUES (:userName, :password, :admin, :tokenID)", insertUser)
_, err := db.DB.NamedExec("INSERT INTO USERS (userName, password, admin, tokenID) VALUES (:userName, :password, :admin, :tokenID)", insertUser)
return err
}
@@ -93,19 +93,19 @@ func ChangePassword(user UserChangePassword) (string, error) {
}
func ChangeName(userName, newName string) error {
_, err := db.DB.Exec("UPDATE USERS SET name = ? WHERE name = ?", newName, userName)
_, err := db.DB.Exec("UPDATE USERS SET userName = ? WHERE userName = ?", newName, userName)
return err
}
func SetAdmin(userName string, admin bool) error {
_, err := db.DB.Exec("UPDATE USERS SET admin = ? WHERE name = ?", admin, userName)
_, err := db.DB.Exec("UPDATE USERS SET admin = ? WHERE userName = ?", admin, userName)
return err
}
func Delete(userName string) error {
_, err := db.DB.Exec("DELETE FROM USERS WHERE name = $1", userName)
_, err := db.DB.Exec("DELETE FROM USERS WHERE userName = $1", userName)
return err
}

View File

@@ -5,130 +5,93 @@ import (
"github.com/johannesbuehl/golunteer/backend/pkg/db/availabilities"
)
func getAvailabilities(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) getAvailabilities() {
// get all the availabilites from the database
if avails, err := availabilities.Slice(); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't get availabilites: %v", err)
return response
} else {
response.Data = avails
return response
a.Data = avails
}
}
func postAvailability(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) postAvailability() {
// check admin
if !args.User.Admin {
response.Status = fiber.StatusUnauthorized
if !a.Admin {
a.Status = fiber.StatusUnauthorized
logger.Warn().Msg("user is no admin")
return response
// parse the body
} else {
var body availabilities.Availability
if err := args.C.BodyParser(&body); err != nil {
response.Status = fiber.StatusBadRequest
if err := a.C.BodyParser(&body); err != nil {
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("can't parse body: %v", err)
return response
// validate the body
} else if err := validate.Struct(&response); err != nil {
response.Status = fiber.StatusBadRequest
} else if err := validate.Struct(&body); err != nil {
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("invalid body: %v", err)
return response
} else if err := availabilities.Add(body); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't add availability: %v", err)
return response
} else {
return response
}
}
}
func patchAvailabilitiy(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) patchAvailabilitiy() {
// check admin
if !args.User.Admin {
response.Status = fiber.StatusUnauthorized
if !a.Admin {
a.Status = fiber.StatusUnauthorized
logger.Warn().Msg("user is no admin")
return response
// parse the body
} else {
var body availabilities.AvailabilityDB
if err := args.C.BodyParser(&body); err != nil {
response.Status = fiber.StatusBadRequest
if err := a.C.BodyParser(&body); err != nil {
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("can't parse body: %v", err)
return response
// validate the body
} else if err := validate.Struct(&response); err != nil {
response.Status = fiber.StatusBadRequest
} else if err := validate.Struct(&body); err != nil {
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("invalid body: %v", err)
return response
} else if err := availabilities.Update(body); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't update availability: %v", err)
return response
} else {
return response
}
}
}
func deleteAvailability(args HandlerArgs) responseMessage {
func (a *Handler) deleteAvailability() {
// check admin
if !args.User.Admin {
if !a.Admin {
logger.Warn().Msg("availability-deletion failed: user is no admin")
return responseMessage{
Status: fiber.StatusUnauthorized,
}
a.Status = fiber.StatusUnauthorized
// parse the query
} else if taskID := args.C.QueryInt("id", -1); taskID == -1 {
logger.Log().Msg("availability-deletion failed: invalid query: doesn't include \"id\"")
} else if taskID := a.C.QueryInt("availabilityID", -1); taskID == -1 {
logger.Log().Msg("availability-deletion failed: invalid query: doesn't include \"availabilityID\"")
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// delete the task from the database
} else if err := availabilities.Delete(taskID); err != nil {
logger.Error().Msgf("availability-deletion failed: can't delete task from database: %v", err)
return responseMessage{
Status: fiber.StatusInternalServerError,
}
} else {
return responseMessage{}
a.Status = fiber.StatusInternalServerError
}
}

View File

@@ -5,144 +5,138 @@ import (
"github.com/johannesbuehl/golunteer/backend/pkg/db/events"
)
func postEvent(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) postEvent() {
// check admin
if !args.User.Admin {
response.Status = fiber.StatusForbidden
if !a.Admin {
a.Status = fiber.StatusForbidden
} else {
// write the event
var body events.EventCreate
// try to parse the body
if err := args.C.BodyParser(&body); err != nil {
response.Status = fiber.StatusBadRequest
if err := a.C.BodyParser(&body); err != nil {
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("can't parse body: %v", err)
// validate the parsed body
} else if err := validate.Struct(body); err != nil {
response.Status = fiber.StatusBadRequest
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("invalid body: %v", err)
// create the event
} else if err := events.Create(body); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't create event: %v", err)
}
}
return response
}
func patchEvent(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) patchEvent() {
// check admin
if !args.User.Admin {
response.Status = fiber.StatusForbidden
if !a.Admin {
a.Status = fiber.StatusForbidden
} else {
// parse the body
var body events.EventPatch
if err := args.C.BodyParser(&body); err != nil {
response.Status = fiber.StatusBadRequest
if err := a.C.BodyParser(&body); err != nil {
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("can't parse body: %v", err)
// validate the body
} else if err := validate.Struct(body); err != nil {
response.Status = fiber.StatusBadRequest
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("ivnalid body: %v", err)
// update the event
} else if err := events.Update(body); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("updating the event failed: %v", err)
}
}
return response
}
func getEventsAssignments(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) getEventsAssignments() {
if events, err := events.WithAssignments(); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't retrieve events with assignments: %v", err)
} else {
response.Data = events
a.Data = events
}
return response
}
func getEventsAvailabilities(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) getEventsAvailabilities() {
// check for admin
if !args.User.Admin {
response.Status = fiber.StatusForbidden
if !a.Admin {
a.Status = fiber.StatusForbidden
} else {
if events, err := events.WithAvailabilities(); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't retrieve events with availabilities: %v", err)
} else {
response.Data = events
a.Data = events
}
}
return response
}
func getEventsUserPending(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) getEventsUserPending() {
if events, err := events.UserPending(a.UserName); err != nil {
a.Status = fiber.StatusInternalServerError
if count, err := events.UserPending(args.User.UserName); err != nil {
response.Status = fiber.StatusInternalServerError
logger.Warn().Msgf("can't query database for users %q pending events: %v", args.User.UserName, err)
logger.Warn().Msgf("can't query database for users %q pending events: %v", a.UserName, err)
} else {
response.Data = count
a.Data = events
}
return response
}
func deleteEvent(args HandlerArgs) responseMessage {
func (a *Handler) getEventsUserPendingCount() {
if count, err := events.UserPendingCount(a.UserName); err != nil {
a.Status = fiber.StatusInternalServerError
logger.Warn().Msgf("can't query database for users %q pending events: %v", a.UserName, err)
} else {
a.Data = count
}
}
func (a *Handler) getEventsUserAssigned() {
// retrieve the events from the database
if events, err := events.User(a.UserName); err != nil {
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("retrieval of user-assigned-events failed: %v", err)
} else {
a.Data = events
}
}
func (a *Handler) deleteEvent() {
// check for admin
if !args.User.Admin {
if !a.Admin {
logger.Warn().Msg("event-delete failed: user is no admin")
return responseMessage{
Status: fiber.StatusForbidden,
}
a.Status = fiber.StatusForbidden
// -1 can't be valid
} else if eventId := args.C.QueryInt("id", -1); eventId == -1 {
logger.Log().Msgf("event-delete failed: \"id\" is missing in query")
} else if eventId := a.C.QueryInt("eventID", -1); eventId == -1 {
logger.Log().Msgf("event-delete failed: \"eventID\" is missing in query")
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
} else if err := events.Delete(eventId); err != nil {
logger.Error().Msgf("event-delete failed: can't delete from database: %v", err)
return responseMessage{
Status: fiber.StatusInternalServerError,
}
a.Status = fiber.StatusInternalServerError
} else {
logger.Log().Msgf("deleted event with id %d", eventId)
return responseMessage{}
logger.Log().Msgf("deleted event with eventID %d", eventId)
}
}

View File

@@ -8,33 +8,32 @@ import (
// handle welcome-messages from clients
func handleWelcome(c *fiber.Ctx) error {
args := Handler{C: c}
logger.Debug().Msgf("HTTP %s request: %q", c.Method(), c.OriginalURL())
response := responseMessage{}
response.Data = UserChecked{
args.Data = UserChecked{
Admin: false,
}
args := HandlerArgs{C: c}
if loggedIn, err := args.checkUser(); err != nil {
response.Status = fiber.StatusInternalServerError
args.Status = fiber.StatusInternalServerError
logger.Warn().Msgf("can't check user: %v", err)
} else if !loggedIn {
response.Status = fiber.StatusUnauthorized
args.Status = fiber.StatusUnauthorized
logger.Debug().Msgf("user not authorized")
} else {
response.Data = UserChecked{
UserName: args.User.UserName,
Admin: args.User.Admin,
args.Data = UserChecked{
UserName: args.UserName,
Admin: args.Admin,
}
logger.Debug().Msgf("welcomed user %q", args.User.UserName)
logger.Debug().Msgf("welcomed user %q", args.UserName)
}
return response.send(c)
return args.send(c)
}
const messageWrongLogin = "Unkown user or wrong password"
@@ -42,7 +41,7 @@ const messageWrongLogin = "Unkown user or wrong password"
func handleLogin(c *fiber.Ctx) error {
logger.Debug().Msgf("HTTP %s request: %q", c.Method(), c.OriginalURL())
args := HandlerArgs{C: c}
args := Handler{C: c}
// extract username and password from the request
requestBody := struct {
@@ -50,12 +49,10 @@ func handleLogin(c *fiber.Ctx) error {
Password string `json:"password" validate:"required"`
}{}
var response responseMessage
if err := args.C.BodyParser(&requestBody); err != nil {
logger.Debug().Msgf("can't parse login-body: %v", err)
response.Status = fiber.StatusBadRequest
args.Status = fiber.StatusBadRequest
// validate the body
} else if err := validate.Struct(requestBody); err != nil {
@@ -63,29 +60,29 @@ func handleLogin(c *fiber.Ctx) error {
} else {
// query the database for the user
var result userDB
if err := db.DB.QueryRowx("SELECT password, admin, tokenID FROM USERS WHERE name = ?", requestBody.Username).StructScan(&result); err != nil {
response.Status = fiber.StatusForbidden
response.Message = messageWrongLogin
if err := db.DB.QueryRowx("SELECT password, admin, tokenID FROM USERS WHERE userName = ?", requestBody.Username).StructScan(&result); err != nil {
args.Status = fiber.StatusForbidden
args.Message = messageWrongLogin
logger.Info().Msgf("can't get user with name = %q from database", requestBody.Username)
logger.Info().Msgf("can't get user with userName = %q from database", requestBody.Username)
} else {
// hash the password
if bcrypt.CompareHashAndPassword(result.Password, []byte(requestBody.Password)) != nil {
response.Status = fiber.StatusForbidden
args.Status = fiber.StatusForbidden
logger.Info().Msgf("login denied: wrong password for user with name = %q", requestBody.Username)
logger.Info().Msgf("login denied: wrong password for user with userName = %q", requestBody.Username)
} else {
// password is correct -> generate the JWT
if jwt, err := config.SignJWT(JWTPayload{
UserName: requestBody.Username,
TokenID: result.TokenID,
}); err != nil {
response.Status = fiber.StatusInternalServerError
args.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't create JWT: %v", err)
} else {
args.setSessionCookie(&jwt)
response.Data = UserChecked{
args.Data = UserChecked{
UserName: requestBody.Username,
Admin: true,
}
@@ -96,18 +93,18 @@ func handleLogin(c *fiber.Ctx) error {
}
}
return response.send(args.C)
return args.send(args.C)
}
// handles logout-requests
func handleLogout(c *fiber.Ctx) error {
logger.Debug().Msgf("HTTP %s request: %q", c.Method(), c.OriginalURL())
args := HandlerArgs{
args := Handler{
C: c,
}
args.removeSessionCookie()
return responseMessage{}.send(c)
return args.send(c)
}

View File

@@ -27,32 +27,33 @@ type responseMessage struct {
}
// answer the client request with the response-message
func (result responseMessage) send(c *fiber.Ctx) error {
func (a *Handler) send(c *fiber.Ctx) error {
// if the status-code is in the error-region, return an error
if result.Status >= 400 {
if a.Status >= 400 {
// if available, include the message
if result.Message != "" {
return fiber.NewError(result.Status, result.Message)
if a.Message != "" {
return fiber.NewError(a.Status, a.Message)
} else {
return fiber.NewError(result.Status)
return fiber.NewError(a.Status)
}
} else {
// if there is data, send it as JSON
if result.Data != nil {
c.JSON(result.Data)
if a.Data != nil {
c.JSON(a.Data)
// if there is a message, send it instead
} else if result.Message != "" {
c.SendString(result.Message)
} else if a.Message != "" {
c.SendString(a.Message)
}
return c.SendStatus(result.Status)
return c.SendStatus(a.Status)
}
}
type HandlerArgs struct {
C *fiber.Ctx
User UserChecked
type Handler struct {
C *fiber.Ctx
UserChecked
responseMessage
}
func init() {
@@ -74,35 +75,45 @@ func init() {
}
// map with the individual registered endpoints
endpoints := map[string]map[string]func(HandlerArgs) responseMessage{
endpoints := map[string]map[string]func(*Handler){
"GET": {
"events/assignments": getEventsAssignments,
"events/availabilities": getEventsAvailabilities,
"events/user/pending": getEventsUserPending,
"tasks": getTasks,
"users": getUsers,
"availabilities": getAvailabilities,
// all events with the task-assignments
"events/assignments": (*Handler).getEventsAssignments,
// all events with the availabilities of the individual users
"events/availabilities": (*Handler).getEventsAvailabilities,
// events the user has to enter his availability for
"events/user/pending": (*Handler).getEventsUserPending,
// number of events the user has to enter his availability for
"events/user/pending/count": (*Handler).getEventsUserPendingCount,
"events/user/assigned": (*Handler).getEventsUserAssigned,
"tasks": (*Handler).getTasks, // all available tasks
"users": (*Handler).getUsers, // all users
"availabilities": (*Handler).getAvailabilities, // all available availabilities
},
"POST": {
"events": postEvent,
"users": postUser,
"availabilities": postAvailability,
"tasks": postTask,
"events": (*Handler).postEvent, // create an event
"users": (*Handler).postUser, // add an user
"availabilities": (*Handler).postAvailability, // add an availability
"tasks": (*Handler).postTask, // add a task
},
"PATCH": {
"users": patchUser,
"events": patchEvent,
"availabilities": patchAvailabilitiy,
"tasks": patchTask,
"users": (*Handler).patchUser, // modify an user
"events": (*Handler).patchEvent, // modify an event
"availabilities": (*Handler).patchAvailabilitiy, // modify an availability
"tasks": (*Handler).patchTask, // modify a task
},
"PUT": {
"users/password": putPassword,
"users/password": (*Handler).putPassword, // change the password
},
"DELETE": {
"event": deleteEvent,
"tasks": deleteTask,
"availabilities": deleteAvailability,
"users": deleteUser,
"event": (*Handler).deleteEvent, // remove an event
"tasks": (*Handler).deleteTask, // remove a task
"availabilities": (*Handler).deleteAvailability, // remove an availability
"users": (*Handler).deleteUser, // remove an user
},
}
@@ -117,28 +128,23 @@ func init() {
handleMethods[method]("/api/"+address, func(c *fiber.Ctx) error {
logger.Debug().Msgf("HTTP %s request: %q", c.Method(), c.OriginalURL())
var response responseMessage
args := HandlerArgs{
args := Handler{
C: c,
}
if loggedIn, err := args.checkUser(); err != nil {
response = responseMessage{
Status: fiber.StatusBadRequest,
}
args.Status = fiber.StatusBadRequest
logger.Error().Msgf("can't check user: %v", err)
} else if !loggedIn {
response = responseMessage{
Status: fiber.StatusUnauthorized,
}
args.Status = fiber.StatusUnauthorized
logger.Log().Msgf("user not authorized")
} else {
response = handler(args)
}
return response.send(c)
handler(&args)
return args.send(c)
})
}
}
@@ -151,7 +157,7 @@ func Listen() {
fmt.Println(err)
}
func (args HandlerArgs) setSessionCookie(jwt *string) {
func (args Handler) setSessionCookie(jwt *string) {
var value string
if jwt == nil {
@@ -170,7 +176,7 @@ func (args HandlerArgs) setSessionCookie(jwt *string) {
}
// removes the session-coockie from a request
func (args HandlerArgs) removeSessionCookie() {
func (args Handler) removeSessionCookie() {
args.C.Cookie(&fiber.Cookie{
Name: "session",
Value: "",
@@ -233,7 +239,7 @@ type UserChecked struct {
}
// checks wether the request is from a valid user
func (args *HandlerArgs) checkUser() (bool, error) {
func (args *Handler) checkUser() (bool, error) {
userName, tokenID, err := extractJWT(args.C)
if err != nil {
@@ -246,7 +252,7 @@ func (args *HandlerArgs) checkUser() (bool, error) {
}
// retrieve the user from the database
if err := db.DB.Get(&dbResult, "SELECT tokenID, admin FROM USERS WHERE name = ?", userName); err != nil {
if err := db.DB.Get(&dbResult, "SELECT tokenID, admin FROM USERS WHERE userName = ?", userName); err != nil {
return false, err
// if the tokenID is valid, the user is authorized
@@ -256,11 +262,9 @@ func (args *HandlerArgs) checkUser() (bool, error) {
// reset the expiration of the cookie
args.setSessionCookie(nil)
args.User = UserChecked{
UserName: userName,
Admin: dbResult.Admin,
}
return true, nil
args.UserName = userName
args.Admin = dbResult.Admin
}
return true, nil
}

View File

@@ -5,125 +5,93 @@ import (
"github.com/johannesbuehl/golunteer/backend/pkg/db/tasks"
)
func getTasks(args HandlerArgs) responseMessage {
func (a *Handler) getTasks() {
if taskSlice, err := tasks.GetSlice(); err != nil {
logger.Error().Msgf("can't get tasks: %v", err)
return responseMessage{
Status: fiber.StatusInternalServerError,
}
a.Status = fiber.StatusInternalServerError
} else {
return responseMessage{
Data: taskSlice,
}
a.Data = taskSlice
}
}
func postTask(args HandlerArgs) responseMessage {
func (a *Handler) postTask() {
// check admin
if !args.User.Admin {
if !a.Admin {
logger.Log().Msgf("user is not admin")
return responseMessage{
Status: fiber.StatusUnauthorized,
}
a.Status = fiber.StatusUnauthorized
} else {
// parse the body
var task tasks.Task
if err := args.C.BodyParser(&task); err != nil {
if err := a.C.BodyParser(&task); err != nil {
logger.Log().Msgf("can't parse body: %v", err)
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// validate the body
} else if err := validate.Struct(&task); err != nil {
logger.Log().Msgf("invalid body: %v", err)
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// insert the task into the database
} else if err := tasks.Add(task); err != nil {
logger.Error().Msgf("can't add task: %v", err)
return responseMessage{
Status: fiber.StatusInternalServerError,
}
} else {
return responseMessage{}
a.Status = fiber.StatusInternalServerError
}
}
}
func patchTask(args HandlerArgs) responseMessage {
func (a *Handler) patchTask() {
// check admin
if !args.User.Admin {
if !a.Admin {
logger.Log().Msgf("user is not admin")
return responseMessage{
Status: fiber.StatusUnauthorized,
}
a.Status = fiber.StatusUnauthorized
} else {
// parse the body
var task tasks.TaskDB
if err := args.C.BodyParser(&task); err != nil {
if err := a.C.BodyParser(&task); err != nil {
logger.Log().Msgf("can't parse body: %v", err)
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// validate the body
} else if err := validate.Struct(&task); err != nil {
logger.Log().Msgf("invalid body: %v", err)
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// insert the task into the database
} else if err := tasks.Update(task); err != nil {
logger.Error().Msgf("can't update task: %v", err)
return responseMessage{
Status: fiber.StatusInternalServerError,
}
} else {
return responseMessage{}
a.Status = fiber.StatusInternalServerError
}
}
}
func deleteTask(args HandlerArgs) responseMessage {
func (a *Handler) deleteTask() {
// check admin
if !args.User.Admin {
if !a.Admin {
logger.Warn().Msg("task-deletion failed: user is no admin")
return responseMessage{
Status: fiber.StatusUnauthorized,
}
a.Status = fiber.StatusUnauthorized
// parse the query
} else if taskID := args.C.QueryInt("id", -1); taskID == -1 {
logger.Log().Msg("task-deletion failed: invalid query: doesn't include \"id\"")
} else if taskID := a.C.QueryInt("taskID", -1); taskID == -1 {
logger.Log().Msg("task-deletion failed: invalid query: doesn't include \"taskID\"")
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// delete the task from the database
} else if err := tasks.Delete(taskID); err != nil {
logger.Error().Msgf("task-deletion failed: can't delete task from database: %v", err)
return responseMessage{
Status: fiber.StatusInternalServerError,
}
} else {
return responseMessage{}
a.Status = fiber.StatusInternalServerError
}
}

View File

@@ -5,76 +5,75 @@ import (
"github.com/johannesbuehl/golunteer/backend/pkg/db/users"
)
func getUsers(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) getUsers() {
// check admin
if !args.User.Admin {
response.Status = fiber.StatusForbidden
if !a.Admin {
a.Status = fiber.StatusForbidden
logger.Log().Msgf("user is no admin")
} else if users, err := users.Get(); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't get users: %v", err)
} else {
response.Data = users
a.Data = users
}
return response
}
func postUser(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) postUser() {
// check admin
if !args.User.Admin {
response.Status = fiber.StatusForbidden
if !a.Admin {
a.Status = fiber.StatusForbidden
logger.Log().Msgf("user is no admin")
} else {
// parse the body
var body users.UserAdd
if err := args.C.BodyParser(&body); err != nil {
response.Status = fiber.StatusBadRequest
if err := a.C.BodyParser(&body); err != nil {
a.Status = fiber.StatusBadRequest
logger.Warn().Msgf("can't parse body: %v", err)
// validate the body
} else if err := validate.Struct(body); err != nil {
response.Status = fiber.StatusBadRequest
a.Status = fiber.StatusBadRequest
logger.Warn().Msgf("invalid body: %v", err)
} else if err := users.Add(body); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Warn().Msgf("can't add user: %v", err)
}
}
return response
}
func putPassword(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) putPassword() {
// parse the body
var body users.UserChangePassword
if err := args.C.BodyParser(&body); err != nil {
response.Status = fiber.StatusBadRequest
if err := a.C.BodyParser(&body); err != nil {
logger.Log().Msgf("can't parse body: %v", err)
a.Status = fiber.StatusBadRequest
// body has been parsed successfully
} else {
body.UserName = args.User.UserName
body.UserName = a.UserName
// validate the body
if err := validate.Struct(body); err != nil {
response.Status = fiber.StatusBadRequest
logger.Info().Msgf("invalid body: %v", err)
} else if tokenID, err := users.ChangePassword(body); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusBadRequest
// send the password change to the database and get the new tokenID back
} else if tokenID, err := users.ChangePassword(body); err != nil {
logger.Error().Msgf("can't update password: %v", err)
a.Status = fiber.StatusInternalServerError
// sign a new JWT with the new tokenID
} else if jwt, err := config.SignJWT(JWTPayload{
UserName: body.UserName,
@@ -82,23 +81,22 @@ func putPassword(args HandlerArgs) responseMessage {
// if something failed, remove the current session-cookie
}); err != nil {
args.removeSessionCookie()
a.removeSessionCookie()
a.Status = fiber.StatusPartialContent
// set the new session-cookie
} else {
// update the token in the session-cookie
args.setSessionCookie(&jwt)
a.setSessionCookie(&jwt)
}
}
return response
}
func patchUser(args HandlerArgs) responseMessage {
response := responseMessage{}
func (a *Handler) patchUser() {
// check admin
if !args.User.Admin {
response.Status = fiber.StatusForbidden
if !a.Admin {
a.Status = fiber.StatusForbidden
logger.Log().Msgf("user is no admin")
} else {
@@ -108,20 +106,20 @@ func patchUser(args HandlerArgs) responseMessage {
NewName string `json:"newName"`
}
if err := args.C.BodyParser(&body); err != nil {
response.Status = fiber.StatusBadRequest
if err := a.C.BodyParser(&body); err != nil {
a.Status = fiber.StatusBadRequest
logger.Log().Msgf("can't parse body: %v", err)
// prevent to demoting self from admin
} else if !body.Admin && body.UserName == args.User.UserName {
response.Status = fiber.StatusBadRequest
} else if !body.Admin && body.UserName == a.UserName {
a.Status = fiber.StatusBadRequest
logger.Warn().Msgf("can't demote self from admin")
} else {
// check for an empty user-name
if len(body.UserName) == 0 {
response.Status = fiber.StatusBadRequest
a.Status = fiber.StatusBadRequest
logger.Warn().Msgf("username is empty")
@@ -135,36 +133,36 @@ func patchUser(args HandlerArgs) responseMessage {
}
if _, err = users.ChangePassword(usePasswordChange); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't change password: %v", err)
return response
return
}
}
// only change the name, if it differs
if body.NewName != body.UserName {
if err := users.ChangeName(body.UserName, body.NewName); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't change user-name: %v", err)
return response
return
}
}
// set the admin-status
if err := users.SetAdmin(body.NewName, body.Admin); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("updating admin-status failed: %v", err)
} else {
// if we modified ourself, update the session-cookie
if body.UserName == args.User.UserName {
if body.UserName == a.UserName {
// get the tokenID
if tokenID, err := users.TokenID(body.NewName); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("can't get tokenID: %v", err)
@@ -172,65 +170,51 @@ func patchUser(args HandlerArgs) responseMessage {
UserName: body.NewName,
TokenID: tokenID,
}); err != nil {
response.Status = fiber.StatusInternalServerError
a.Status = fiber.StatusInternalServerError
logger.Error().Msgf("JWT-signing failed: %v", err)
// remove the session-cookie
args.removeSessionCookie()
a.removeSessionCookie()
} else {
args.setSessionCookie(&jwt)
a.setSessionCookie(&jwt)
}
}
}
}
}
}
return response
}
func deleteUser(args HandlerArgs) responseMessage {
func (a *Handler) deleteUser() {
// check admin
if !args.User.Admin {
if !a.Admin {
logger.Warn().Msg("user-deletion failed: user is no admin")
return responseMessage{
Status: fiber.StatusUnauthorized,
}
a.Status = fiber.StatusUnauthorized
// get the username from the query
} else if userName := args.C.Query("userName"); userName == "" {
} else if userName := a.C.Query("userName"); userName == "" {
logger.Log().Msg("user-deletion failed: query is missing \"userName\"")
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// check wether the user tries to delete himself
} else if userName == args.User.UserName {
} else if userName == a.UserName {
logger.Log().Msg("user-deletion failed: self-deletion is illegal")
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// check wether the user tries to delete the admin
} else if userName == "admin" {
logger.Log().Msg("user-deletion failed: admin-deletion is illegal")
return responseMessage{
Status: fiber.StatusBadRequest,
}
a.Status = fiber.StatusBadRequest
// delete the user
} else if err := users.Delete(userName); err != nil {
logger.Error().Msgf("user-deletion failed: user doesn't exist")
return responseMessage{
Status: fiber.StatusNotFound,
}
} else {
return responseMessage{}
a.Status = fiber.StatusNotFound
}
}

View File

@@ -1,18 +1,18 @@
CREATE TABLE IF NOT EXISTS TASKS (
id INTEGER PRIMARY KEY,
name varchar(64) NOT NULL,
taskID INTEGER PRIMARY KEY,
taskName varchar(64) NOT NULL,
enabled BOOL DEFAULT 1
);
CREATE TABLE IF NOT EXISTS AVAILABILITIES (
id INTEGER PRIMARY KEY,
name varchar(32) NOT NULL,
availabilityID INTEGER PRIMARY KEY,
availabilityName varchar(32) NOT NULL,
color varchar(7) NOT NULL,
enabled BOOL DEFAULT 1
);
CREATE TABLE IF NOT EXISTS USERS (
name varchar(64) PRIMARY KEY,
userName varchar(64) PRIMARY KEY,
password BLOB NOT NULL,
admin BOOL NOT NULL DEFAULT(false),
tokenID varchar(64) NOT NULL,
@@ -21,7 +21,7 @@ CREATE TABLE IF NOT EXISTS USERS (
);
CREATE TABLE IF NOT EXISTS EVENTS (
id INTEGER PRIMARY KEY,
eventID INTEGER PRIMARY KEY,
date DATETIME NOT NULL,
description TEXT DEFAULT ""
);
@@ -31,9 +31,9 @@ CREATE TABLE IF NOT EXISTS USER_AVAILABILITIES (
eventID INTEGER NOT NULL,
availabilityID INTEGER NOT NULL,
PRIMARY KEY (userName, eventID),
FOREIGN KEY (userName) REFERENCES USERS(name) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (eventID) REFERENCES EVENTS(id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (availabilityID) REFERENCES AVAILABILITIES(id) ON UPDATE CASCADE
FOREIGN KEY (userName) REFERENCES USERS(userName) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (eventID) REFERENCES EVENTS(eventID) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (availabilityID) REFERENCES AVAILABILITIES(availabilityID) ON UPDATE CASCADE
);
CREATE TABLE IF NOT EXISTS USER_ASSIGNMENTS (
@@ -41,7 +41,7 @@ CREATE TABLE IF NOT EXISTS USER_ASSIGNMENTS (
taskID INTEGER NOT NULL,
userName varchar(64),
PRIMARY KEY (eventID, taskID),
FOREIGN KEY (eventID) REFERENCES EVENTS(id) ON DELETE CASCADE,
FOREIGN KEY (userName) REFERENCES USERS(name) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (taskID) REFERENCES TASKS(id) ON UPDATE CASCADE
FOREIGN KEY (eventID) REFERENCES EVENTS(eventID) ON DELETE CASCADE,
FOREIGN KEY (userName) REFERENCES USERS(userName) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (taskID) REFERENCES TASKS(taskID) ON UPDATE CASCADE
);