- Item 1: Extract GetUserByID/GetChannelByID lookup methods, use from relation methods - Item 2: Initialize slices with literals so JSON gets [] not null - Item 3: Populate CreatedAt/UpdatedAt with time.Now() on all Create methods - Item 4: Wrap each migration's SQL + recording in a transaction - Item 5: Check error from res.LastInsertId() in QueueMessage - Item 6: Add DequeueMessages and AckMessages methods - Item 8: Add GetUserByNick, GetUserByToken, DeleteAuthToken, UpdateUserLastSeen - Item 9: Run PRAGMA foreign_keys = ON on every new connection - Item 10: Builds clean, all tests pass
97 lines
1.8 KiB
Go
97 lines
1.8 KiB
Go
package models
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// Channel represents a chat channel.
|
|
type Channel struct {
|
|
Base
|
|
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Topic string `json:"topic"`
|
|
Modes string `json:"modes"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
UpdatedAt time.Time `json:"updatedAt"`
|
|
}
|
|
|
|
// Members returns all users who are members of this channel.
|
|
func (c *Channel) Members(ctx context.Context) ([]*ChannelMember, error) {
|
|
rows, err := c.GetDB().QueryContext(ctx, `
|
|
SELECT cm.channel_id, cm.user_id, cm.modes, cm.joined_at,
|
|
u.nick
|
|
FROM channel_members cm
|
|
JOIN users u ON u.id = cm.user_id
|
|
WHERE cm.channel_id = ?
|
|
ORDER BY cm.joined_at`,
|
|
c.ID,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer func() { _ = rows.Close() }()
|
|
|
|
members := []*ChannelMember{}
|
|
|
|
for rows.Next() {
|
|
m := &ChannelMember{}
|
|
m.SetDB(c.db)
|
|
|
|
err = rows.Scan(
|
|
&m.ChannelID, &m.UserID, &m.Modes,
|
|
&m.JoinedAt, &m.Nick,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
members = append(members, m)
|
|
}
|
|
|
|
return members, rows.Err()
|
|
}
|
|
|
|
// RecentMessages returns the most recent messages in this channel.
|
|
func (c *Channel) RecentMessages(
|
|
ctx context.Context,
|
|
limit int,
|
|
) ([]*Message, error) {
|
|
rows, err := c.GetDB().QueryContext(ctx, `
|
|
SELECT id, ts, from_user_id, from_nick,
|
|
target, type, body, meta, created_at
|
|
FROM messages
|
|
WHERE target = ?
|
|
ORDER BY ts DESC
|
|
LIMIT ?`,
|
|
c.Name, limit,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer func() { _ = rows.Close() }()
|
|
|
|
messages := []*Message{}
|
|
|
|
for rows.Next() {
|
|
msg := &Message{}
|
|
msg.SetDB(c.db)
|
|
|
|
err = rows.Scan(
|
|
&msg.ID, &msg.Timestamp, &msg.FromUserID,
|
|
&msg.FromNick, &msg.Target, &msg.Type,
|
|
&msg.Body, &msg.Meta, &msg.CreatedAt,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
messages = append(messages, msg)
|
|
}
|
|
|
|
return messages, rows.Err()
|
|
}
|