201 lines
5.0 KiB
Go
201 lines
5.0 KiB
Go
/*
|
|
YetAnotherToDoList
|
|
Copyright © 2023 gilex-dev gilex-dev@proton.me
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, version 3.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package database
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
|
|
"somepi.ddns.net/gitea/gilex-dev/YetAnotherToDoList/graph/model"
|
|
)
|
|
|
|
// GetOwner takes a todoId and return the owner's userId. Call before Update/Get/DeleteTodo when not IS_admin.
|
|
func (db CustomDB) GetOwner(todoId string) (string, error) {
|
|
numTodoId, err := strconv.Atoi(todoId)
|
|
if err != nil {
|
|
return "", errors.New("invalid todoId")
|
|
}
|
|
|
|
statement, err := db.connection.Prepare("SELECT FK_User_userId, FROM Todo WHERE todoId = ?")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
result := statement.QueryRow(numTodoId)
|
|
var owner string
|
|
if err := result.Scan(&owner); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return owner, nil
|
|
}
|
|
|
|
// GetTodo takes a *model.Todo with at least ID set and adds the missing fields.
|
|
func (db CustomDB) GetTodo(todo *model.Todo) (*model.Todo, error) {
|
|
numTodoId, err := strconv.Atoi(todo.ID)
|
|
if err != nil {
|
|
return nil, errors.New("invalid todoId")
|
|
}
|
|
|
|
statement, err := db.connection.Prepare("SELECT text, IS_done, FK_User_userId FROM Todo WHERE todoId = ?")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
todo.User = &model.User{} // TODO: check if this overrides something
|
|
result := statement.QueryRow(numTodoId)
|
|
if err := result.Scan(&todo.Text, &todo.Done, &todo.User.ID); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return todo, nil
|
|
}
|
|
|
|
// GetTodosFrom gets all todos from the passed *model.User. ID must be set.
|
|
func (db CustomDB) GetTodosFrom(user *model.User) ([]*model.Todo, error) {
|
|
id, err := strconv.Atoi(user.ID)
|
|
if err != nil {
|
|
return nil, errors.New("invalid userId")
|
|
}
|
|
statement, err := db.connection.Prepare("SELECT todoId, text, IS_done FROM Todo WHERE FK_User_userId = ?")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rows, err := statement.Query(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
var all []*model.Todo
|
|
for rows.Next() {
|
|
todo := model.Todo{User: user}
|
|
if err := rows.Scan(&todo.ID, &todo.Text, &todo.Done); err != nil {
|
|
return nil, err
|
|
}
|
|
all = append(all, &todo)
|
|
}
|
|
return all, nil
|
|
}
|
|
|
|
// GetAllTodos gets all todos from the database. Check if the source has the rights to call this.
|
|
func (db CustomDB) GetAllTodos() ([]*model.Todo, error) {
|
|
rows, err := db.connection.Query("SELECT todoID, text, IS_done, FK_User_userID FROM Todo")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
var todos []*model.Todo
|
|
for rows.Next() {
|
|
var todo = model.Todo{User: &model.User{}}
|
|
if err := rows.Scan(&todo.ID, &todo.Text, &todo.Done, &todo.User.ID); err != nil {
|
|
return nil, err
|
|
}
|
|
todos = append(todos, &todo)
|
|
}
|
|
return todos, nil
|
|
}
|
|
|
|
// CreateTodo creates a Todo for the passed newTodo.UserID. Check if the source has the rights to call this.
|
|
func (db CustomDB) CreateTodo(newTodo model.NewTodo) (*model.Todo, error) {
|
|
statement, err := db.connection.Prepare("INSERT INTO Todo (text, FK_User_userID) VALUES (?, ?)")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rows, err := statement.Exec(newTodo.Text, newTodo.UserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
num, err := rows.RowsAffected()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if num < 1 {
|
|
return nil, errors.New("no rows affected")
|
|
}
|
|
|
|
insertId, err := rows.LastInsertId()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &model.Todo{ID: strconv.FormatInt(insertId, 10), Text: newTodo.Text, Done: false, User: &model.User{ID: newTodo.UserID}}, nil
|
|
}
|
|
|
|
func (db CustomDB) UpdateTodo(todoId string, changes *model.UpdateTodo) (*model.Todo, error) {
|
|
|
|
numTodoId, err := strconv.Atoi(todoId)
|
|
if err != nil {
|
|
return nil, errors.New("invalid todoId")
|
|
}
|
|
|
|
statement, err := db.connection.Prepare("UPDATE Todo SET text = IFNULL(?, text), IS_done = IFNULL(?, IS_done) WHERE todoId = ?")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rows, err := statement.Exec(changes.Text, changes.Done, numTodoId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
num, err := rows.RowsAffected()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if num < 1 {
|
|
return nil, errors.New("no rows affected")
|
|
}
|
|
|
|
return db.GetTodo(&model.Todo{ID: todoId})
|
|
}
|
|
|
|
func (db CustomDB) DeleteTodo(todoId string) (deletedTodoId *string, err error) {
|
|
numTodoId, err := strconv.Atoi(todoId)
|
|
if err != nil {
|
|
return nil, errors.New("invalid todoId")
|
|
}
|
|
|
|
statement, err := db.connection.Prepare("DELETE FROM Todo WHERE todoId = ?")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rows, err := statement.Exec(numTodoId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
num, err := rows.RowsAffected()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if num < 1 {
|
|
return nil, errors.New("no rows affected")
|
|
}
|
|
|
|
return &todoId, nil
|
|
}
|