From a3c5ed4f4bf5603d7750aef79ae0af3fb7a6a009 Mon Sep 17 00:00:00 2001 From: gamray Date: Sun, 19 May 2024 23:18:42 +0200 Subject: [PATCH] Added unique constraint for friend to not have to manually check if users are already friends --- db/account.go | 35 ++++++++++++++--------------------- db/db.go | 3 ++- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/db/account.go b/db/account.go index ca8ee08..12bc354 100644 --- a/db/account.go +++ b/db/account.go @@ -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 diff --git a/db/db.go b/db/db.go index cfba90b..4b6c32b 100644 --- a/db/db.go +++ b/db/db.go @@ -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)`, }