Added unique constraint for friend to not have to manually check if users are already friends

This commit is contained in:
gamray 2024-05-19 23:18:42 +02:00
parent 9b4e400558
commit a3c5ed4f4b
2 changed files with 16 additions and 22 deletions

View File

@ -23,7 +23,7 @@ import (
"fmt"
"slices"
_ "github.com/go-sql-driver/mysql"
"github.com/go-sql-driver/mysql"
"github.com/pagefaultgames/rogueserver/defs"
)
@ -280,16 +280,6 @@ func FetchUUIDFromUsername(username string) ([]byte, error) {
return uuid, nil
}
func IsFriendWith(sourceUuid []byte, friendUuid []byte) (bool, error) {
var result int
err := handle.QueryRow("SELECT COUNT(*) FROM friends WHERE user = ? AND friend = ?", sourceUuid, friendUuid).Scan(&result)
if err != nil {
return false, err
}
return result == 1, nil
}
func AddFriend(uuid []byte, friendUsername string) (bool, error) {
// We are making db errors more generic as error is used in the response data to the client.
friendUuid, err := FetchUUIDFromUsername(friendUsername)
@ -301,13 +291,12 @@ func AddFriend(uuid []byte, friendUsername string) (bool, error) {
return false, fmt.Errorf("User does not exist")
}
alreadyFriends, _ := IsFriendWith(uuid, friendUuid)
if alreadyFriends {
return false, fmt.Errorf("Already friend with this user")
}
_, err = handle.Exec("INSERT INTO friends (user, friend, since) VALUES (?, ?, UTC_TIMESTAMP())", uuid, friendUuid)
if err != nil {
var mysqlErr *mysql.MySQLError
if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 {
return false, fmt.Errorf("Already friend with this user.")
}
return false, fmt.Errorf("An error occured, if this persist, please contact an administrator.")
}
@ -325,14 +314,18 @@ func RemoveFriend(uuid []byte, friendUsername string) (bool, error) {
return false, fmt.Errorf("User does not exist")
}
alreadyFriends, _ := IsFriendWith(uuid, friendUuid)
if !alreadyFriends {
return false, fmt.Errorf("You are not friend with this user")
result, err := handle.Exec("DELETE FROM friends WHERE user = ? AND friend = ?", uuid, friendUuid)
if err != nil {
return false, fmt.Errorf("An error occured, if this persist, please contact an administrator.")
}
_, err = handle.Exec("DELETE FROM friends WHERE user = ? AND friend = ?", uuid, friendUuid)
affected, err := result.RowsAffected()
if err != nil {
return false, err
return false, fmt.Errorf("An error occured, if this persist, please contact an administrator.")
}
if affected == 0 {
return false, fmt.Errorf("You are not friend with this user.")
}
return true, nil

View File

@ -183,7 +183,8 @@ func setupDb(tx *sql.Tx) error {
friend BINARY(16) NOT NULL,
since DATE NOT NULL,
FOREIGN KEY (user) REFERENCES accounts (uuid) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (friend) REFERENCES accounts (uuid) ON DELETE CASCADE ON UPDATE CASCADE
FOREIGN KEY (friend) REFERENCES accounts (uuid) ON DELETE CASCADE ON UPDATE CASCADE,
UNIQUE (user, friend)
)`,
`CREATE INDEX IF NOT EXISTS allUserFriends ON friends (user)`,
}