package api import ( "errors" "fmt" "log/slog" "git.dubyatp.xyz/chat-api-server/db" "github.com/gocql/gocql" ) 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) { query := `SELECT id, name, password FROM users WHERE name = ?` 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 (jwttoken, userid, expiry) VALUES (?, ?, ?)` err := db.Session.Query(query, session.Token, session.UserID, session.Expiry).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", "userID", session.UserID) return nil } func dbGetSession(jwtToken string) (*Session, error) { query := `SELECT jwttoken, userid, expiry FROM sessions WHERE jwttoken = ?` var session Session err := db.Session.Query(query, jwtToken).Scan( &session.Token, &session.UserID, &session.Expiry) 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(jwtToken string) error { query := `DELETE FROM sessions WHERE jwttoken = ?` err := db.Session.Query(query, jwtToken).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 }