From 51b426ba54a7f08c96a04ebb861e8ce108a55d04 Mon Sep 17 00:00:00 2001 From: slawk0 Date: Thu, 6 Feb 2025 21:57:44 +0100 Subject: [PATCH] added contact suggestion route, code refactor --- database/auth.go | 10 +++++----- database/contacts.go | 29 +++++++++++++++++++++++++++++ handlers/auth.go | 4 ++-- handlers/contacts.go | 28 ++++++++++++++++++++++++---- model/model.go | 4 ++++ router/router.go | 1 + 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/database/auth.go b/database/auth.go index 79ad7f8..cc23e2f 100644 --- a/database/auth.go +++ b/database/auth.go @@ -11,13 +11,13 @@ import ( func CheckUserExists(db *sql.DB, username string) (bool, error) { query := `SELECT COUNT(1) FROM accounts WHERE username = $1` - var exist bool - err := db.QueryRow(query, username).Scan(&exist) - if !errors.Is(err, sql.ErrNoRows) { - return false, helpers.NewError(helpers.ErrInternal, "Failed to check username", err) + var count int + err := db.QueryRow(query, username).Scan(&count) + if err != nil { + return false, helpers.NewError(helpers.ErrInternal, "Failed to check user existence", err) } - return exist, nil + return count > 0, nil } func InsertUser(db *sql.DB, username string, passwordHash string) (string, error) { diff --git a/database/contacts.go b/database/contacts.go index 682b5f3..66f402e 100644 --- a/database/contacts.go +++ b/database/contacts.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "relay-server/helpers" "relay-server/model" + "strings" ) func DeleteContact(db *sql.DB, userID uuid.UUID, conversationID uuid.UUID) error { @@ -317,3 +318,31 @@ func GetContacts(db *sql.DB, userID uuid.UUID) ([]*model.Contact, error) { return contacts, nil } + +func ContactSuggestion(db *sql.DB, contactUsername string) ([]string, error) { + query := ` + SELECT username FROM accounts + WHERE LOWER(username) LIKE $1 + LIMIT 5; + ` + + rows, err := db.Query(query, "%"+strings.ToLower(contactUsername)+"%") + + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil, helpers.NewError(helpers.ErrInternal, "Failed to get contact suggestions", err) + } + + var suggestions []string + for rows.Next() { + var suggestion string + err := rows.Scan(&suggestion) + if err != nil { + return nil, helpers.NewError(helpers.ErrInternal, "internal server error", err) + } + suggestions = append(suggestions, suggestion) + } + if err = rows.Err(); err != nil { + return nil, helpers.NewError(helpers.ErrInternal, "Error processing suggestions", err) + } + return suggestions, nil +} diff --git a/handlers/auth.go b/handlers/auth.go index b9e8949..1e64b2c 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -40,7 +40,7 @@ func Signup(c *fiber.Ctx) error { // Check if user exists exist, err := database.CheckUserExists(database.DB, u.Username) if err != nil { - return helpers.NewError(helpers.ErrInternal, "internal server error", fmt.Errorf("failed to check user existance: %w", err)) + return err } if exist { return helpers.NewError(helpers.ErrInvalidInput, "User already exists", nil) @@ -55,7 +55,7 @@ func Signup(c *fiber.Ctx) error { // Insert user userID, err := database.InsertUser(database.DB, u.Username, string(passwordHash)) if err != nil { - return helpers.NewError(helpers.ErrInternal, "Failed to create user", err) + return err } // Generate token diff --git a/handlers/contacts.go b/handlers/contacts.go index 0011f54..29e8e12 100644 --- a/handlers/contacts.go +++ b/handlers/contacts.go @@ -9,8 +9,8 @@ import ( func DeleteContact(c *fiber.Ctx) error { type params struct { - ContactID uuid.UUID `params:"contact_id"` - ConversationID uuid.UUID `params:"conversation_id"` + ContactID uuid.UUID `params:"contactID"` + ConversationID uuid.UUID `params:"conversationID"` } p := new(params) @@ -27,7 +27,7 @@ func DeleteContact(c *fiber.Ctx) error { err := database.DeleteContact(database.DB, p.ContactID, p.ConversationID) if err != nil { - return helpers.NewError(helpers.ErrInternal, "Failed to delete contact", err) + return err } return c.Status(fiber.StatusOK).JSON(fiber.Map{"message": "Contact deleted"}) @@ -59,7 +59,7 @@ func InsertContact(c *fiber.Ctx) error { } if !helpers.IsValidUsername(p.ContactUsername) { - return helpers.NewError(helpers.ErrInvalidInput, "username is invalid", nil) + return helpers.NewError(helpers.ErrInvalidInput, "invalid username", nil) } contactID, err := database.GetUserID(database.DB, p.ContactUsername) @@ -94,3 +94,23 @@ func GetContacts(c *fiber.Ctx) error { return c.Status(fiber.StatusOK).JSON(contacts) } + +func GetContactSuggestions(c *fiber.Ctx) error { + type params struct { + ContactUsername string `params:"contactUsername"` + } + + p := new(params) + if err := c.ParamsParser(p); err != nil { + return helpers.NewError(helpers.ErrInvalidInput, "Invalid params", err) + } + if p.ContactUsername == "" { + return helpers.NewError(helpers.ErrInvalidInput, "contact username is empty", nil) + } + + suggestions, err := database.ContactSuggestion(database.DB, p.ContactUsername) + if err != nil { + return err + } + return c.Status(fiber.StatusOK).JSON(suggestions) +} diff --git a/model/model.go b/model/model.go index 5d3ac96..a347330 100644 --- a/model/model.go +++ b/model/model.go @@ -21,3 +21,7 @@ type Contact struct { LastMessageTime string `json:"last_message_time"` LastMessageSender string `json:"last_message_sender"` } + +type ContactSuggestion struct { + Username string `json:"username"` +} diff --git a/router/router.go b/router/router.go index 33c3487..905d40b 100644 --- a/router/router.go +++ b/router/router.go @@ -25,4 +25,5 @@ func SetupRoutes(app *fiber.App) { contacts.Delete("/:contact_id/:conversation_id", handlers.DeleteContact) contacts.Post("/:contact_username", handlers.InsertContact) contacts.Get("/", handlers.GetContacts) + contacts.Get("/suggestions/:contactUsername", handlers.GetContactSuggestions) }