package models import ( "database/sql" "regexp" "time" ) type ChatMessage struct { ID int `json:"id"` UserID int `json:"userId"` Content string `json:"content"` ReplyTo int `json:"replyTo"` Timestamp time.Time `json:"timestamp"` Username string `json:"username"` PfpFileID sql.NullInt64 `json:"pfpFileId"` Mentions []string `json:"mentions"` } func CreateChatMessage(db *sql.DB, msg ChatMessage) error { query := "INSERT INTO chat_messages (user_id, content, reply_to, timestamp) VALUES (?, ?, ?, NOW())" _, err := db.Exec(query, msg.UserID, msg.Content, msg.ReplyTo) return err } func GetRecentChatMessages(db *sql.DB, limit int) ([]ChatMessage, error) { query := ` SELECT cm.id, cm.user_id, cm.content, cm.reply_to, cm.timestamp, u.username, u.pfp_file_id FROM chat_messages cm JOIN users u ON cm.user_id = u.id ORDER BY cm.timestamp DESC LIMIT ?` rows, err := db.Query(query, limit) if err != nil { return nil, err } defer rows.Close() var messages []ChatMessage for rows.Next() { var msg ChatMessage var timestampStr string err := rows.Scan(&msg.ID, &msg.UserID, &msg.Content, &msg.ReplyTo, ×tampStr, &msg.Username, &msg.PfpFileID) if err != nil { return nil, err } msg.Timestamp, err = time.Parse("2006-01-02 15:04:05", timestampStr) if err != nil { msg.Timestamp = time.Time{} } msg.Mentions = extractMentions(msg.Content) messages = append(messages, msg) } return messages, nil } func GetChatMessageByID(db *sql.DB, id int) (*ChatMessage, error) { query := ` SELECT cm.id, cm.user_id, cm.content, cm.reply_to, cm.timestamp, u.username, u.pfp_file_id FROM chat_messages cm JOIN users u ON cm.user_id = u.id WHERE cm.id = ?` row := db.QueryRow(query, id) var msg ChatMessage var timestampStr string err := row.Scan(&msg.ID, &msg.UserID, &msg.Content, &msg.ReplyTo, ×tampStr, &msg.Username, &msg.PfpFileID) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } msg.Timestamp, err = time.Parse("2006-01-02 15:04:05", timestampStr) if err != nil { msg.Timestamp = time.Time{} } msg.Mentions = extractMentions(msg.Content) return &msg, nil } func GetUsernamesMatching(db *sql.DB, prefix string) ([]string, error) { query := "SELECT username FROM users WHERE username LIKE ? LIMIT 10" rows, err := db.Query(query, prefix+"%") if err != nil { return nil, err } defer rows.Close() var usernames []string for rows.Next() { var username string if err := rows.Scan(&username); err != nil { return nil, err } usernames = append(usernames, username) } return usernames, nil } // Simple utility to extract mentions from content func extractMentions(content string) []string { re := regexp.MustCompile(`@(\w+)`) matches := re.FindAllStringSubmatch(content, -1) mentions := make([]string, len(matches)) for i, match := range matches { mentions[i] = match[1] } return mentions }