package api import ( "errors" "fmt" "log/slog" "git.dubyatp.xyz/chat-api-server/db" "github.com/gocql/gocql" "github.com/google/uuid" ) func dbGetUser(id string) (*User, error) { query := `SELECT id, name, password FROM users WHERE id = ?` var user User err := db.Session.Query(query, id).Scan(&user.ID, &user.Name, &user.Password) if err == gocql.ErrNotFound { slog.Debug("db: user not found", "userid", id) return nil, errors.New("User not found") } else if err != nil { slog.Error("db: failed to query user", "error", err) return nil, fmt.Errorf("failed to query user") } slog.Debug("db: user found", "userid", user.ID, "username", user.Name) return &user, nil } func dbGetUserByName(username string) (*User, error) { // This will be deprecated soon after implementing https://git.dubyatp.xyz/williamp/chatservice_concept/issues/1 query := `SELECT id, name, password FROM users WHERE name = ? ALLOW FILTERING` var user User err := db.Session.Query(query, username).Scan(&user.ID, &user.Name, &user.Password) if err == gocql.ErrNotFound { slog.Debug("db: user not found", "username", username) return nil, errors.New("User not found") } else if err != nil { slog.Error("db: failed to query user", "error", err) return nil, fmt.Errorf("failed to query user") } slog.Debug("db: user found", "userid", user.ID, "username", user.Name) return &user, nil } func dbGetAllUsers() ([]*User, error) { query := `SELECT id, name, password FROM users` iter := db.Session.Query(query).Iter() defer iter.Close() var users []*User for { user := &User{} if !iter.Scan(&user.ID, &user.Name, &user.Password) { break } users = append(users, user) } if err := iter.Close(); err != nil { slog.Error("db: failed to iterate users", "error", err) return nil, fmt.Errorf("failed to iterate users") } if len(users) == 0 { slog.Debug("db: no users found") return nil, errors.New("no users found") } slog.Debug("db: user list returned") return users, nil } func dbGetMessage(id string) (*Message, error) { query := `SELECT id, body, edited, timestamp, userid FROM messages WHERE id = ?` var message Message err := db.Session.Query(query, id).Scan( &message.ID, &message.Body, &message.Edited, &message.Timestamp, &message.UserID) if err == gocql.ErrNotFound { slog.Debug("db: message not found", "messageid", id) return nil, errors.New("Message not found") } else if err != nil { slog.Error("db: failed to query message", "error", err) return nil, fmt.Errorf("failed to query message") } slog.Debug("db: message found", "messageid", message.ID) return &message, nil } func dbGetAllMessages() ([]*Message, error) { query := `SELECT id, body, edited, timestamp, userid FROM messages` iter := db.Session.Query(query).Iter() defer iter.Close() var messages []*Message for { message := &Message{} if !iter.Scan( &message.ID, &message.Body, &message.Edited, &message.Timestamp, &message.UserID) { break } messages = append(messages, message) } if err := iter.Close(); err != nil { slog.Error("db: failed to iterate messages", "error", err) return nil, fmt.Errorf("failed to iterate messages") } if len(messages) == 0 { slog.Debug("db: no messages found") return nil, errors.New("no messages found") } slog.Debug("db: message list returned") return messages, nil } func dbAddSession(session *Session) error { query := `INSERT INTO sessions (session_token, username) VALUES (?, ?)` err := db.Session.Query(query, session.Token, session.Username).Exec() if err != nil { slog.Error("db: failed to add session", "error", err) return fmt.Errorf("failed to add session") } slog.Debug("db: session added", "username", session.Username) return nil } func dbGetSession(id uuid.UUID) (*Session, error) { query := `SELECT session_token, username FROM sessions WHERE session_token = ?` var session Session err := db.Session.Query(query, id).Scan( &session.Token, &session.Username) if err == gocql.ErrNotFound { slog.Debug("db: session not found") return nil, errors.New("Session not found") } else if err != nil { slog.Error("db: failed to query session", "error", err) return nil, fmt.Errorf("failed to query session") } return &session, nil } func dbDeleteSession(id uuid.UUID) error { query := `DELETE FROM sessions WHERE session_token = ?` err := db.Session.Query(query, id).Exec() if err != nil { slog.Error("db: failed to delete session") return fmt.Errorf("failed to delete session") } slog.Debug("db: session deleted") return nil } func dbAddUser(user *User) error { query := `INSERT INTO users (id, name, password) VALUES (?, ?, ?)` err := db.Session.Query(query, user.ID, user.Name, user.Password).Exec() if err != nil { slog.Error("db: failed to add user", "error", err, "userid", user.ID, "username", user.Name) return fmt.Errorf("failed to add user") } slog.Debug("db: user added", "userid", user.ID, "username", user.Name) return nil } func dbAddMessage(message *Message) error { query := `INSERT INTO messages (id, body, edited, timestamp, userid) VALUES (?, ?, ?, ?, ?)` err := db.Session.Query(query, message.ID, message.Body, nil, message.Timestamp, message.UserID).Exec() if err != nil { slog.Error("db: failed to add message", "error", err, "messageid", message.ID) return fmt.Errorf("failed to add message") } slog.Debug("db: message added", "messageid", message.ID) return nil } func dbUpdateMessage(updatedMessage *Message) error { var edited interface{} if updatedMessage.Edited.IsZero() { edited = nil } else { edited = updatedMessage.Edited } query := `UPDATE messages SET body = ?, edited = ?, timestamp = ? WHERE ID = ?` err := db.Session.Query(query, updatedMessage.Body, edited, updatedMessage.Timestamp, updatedMessage.ID).Exec() if err != nil { slog.Error("db: failed to update message", "error", err, "messageid", updatedMessage.ID) return fmt.Errorf("failed to update message") } slog.Debug("db: message updated", "messageid", updatedMessage.ID) return nil } func dbDeleteMessage(id string) error { query := `DELETE FROM messages WHERE ID = ?` err := db.Session.Query(query, id).Exec() if err != nil { slog.Error("db: failed to delete message", "error", err, "messageid", id) return fmt.Errorf("failed to delete message") } slog.Debug("db: message deleted", "messageid", id) return nil }