Started working on refactoring packet types and some changes to the SQL

schema
This commit is contained in:
2024-11-27 07:47:30 +02:00
parent 195a2912b7
commit 8ed2527a88
9 changed files with 282 additions and 159 deletions

View File

@@ -92,3 +92,39 @@ func GetUserById(id snowflake.ID) tea.Cmd {
}
}
func CreateServer(
name string,
icon string,
bgHexColor string,
fgHexColor string,
isPublic bool,
) tea.Cmd {
return func() tea.Msg {
requestName := "CreateServer"
log.Println("request", requestName, "sent")
request := packet.CreateNetwork{
Name: name,
Icon: icon,
BgHexColor: bgHexColor,
FgHexColor: fgHexColor,
IsPublic: isPublic,
}
response, ok := <-gateway.Send(&request)
if !ok {
return fmt.Errorf("request %s timeout", requestName)
}
log.Println("request", requestName, "received response")
switch response := response.(type) {
case *packet.ErrorMessage:
return errors.New(response.Error)
case *packet.Users:
if len(response.Users) == 0 {
return fmt.Errorf("requested user id %v not found", id)
}
assert.Assert(len(response.Users) == 1, "server must return only one user with the matching id")
return UserProfileUpdate(response.Users[0])
}
return fmt.Errorf("received invalid response from server: %v", response.Type())
}
}

View File

@@ -37,18 +37,11 @@ type Network struct {
IsPublic bool
}
type NetworkBannedUser struct {
NetworkID snowflake.ID
BannedUserID snowflake.ID
BannedAt string
Reason *string
}
type User struct {
ID snowflake.ID
Name string
PublicKey ed25519.PublicKey
Description *string
Description string
IsPublicDM bool
IsDeleted bool
}
@@ -68,6 +61,9 @@ type UsersNetwork struct {
UserID snowflake.ID
NetworkID snowflake.ID
JoinedAt string
IsMember bool
IsAdmin bool
IsMuted bool
IsBanned bool
BanReason *string
}

View File

@@ -67,17 +67,15 @@ func (q *Queries) DeleteNetwork(ctx context.Context, id snowflake.ID) error {
const getBannedUsersInNetwork = `-- name: GetBannedUsersInNetwork :many
SELECT
users.id, users.name, users.public_key, users.description, users.is_public_dm, users.is_deleted,
network_banned_users.banned_at,
network_banned_users.reason
FROM network_banned_users
JOIN users ON users.id = network_banned_users.banned_user_id
WHERE network_banned_users.network_id = ?
users_networks.ban_reason
FROM users_networks
JOIN users ON users.id = users_networks.user_id
WHERE users_networks.network_id = ?
`
type GetBannedUsersInNetworkRow struct {
User User
BannedAt string
Reason *string
User User
BanReason *string
}
func (q *Queries) GetBannedUsersInNetwork(ctx context.Context, networkID snowflake.ID) ([]GetBannedUsersInNetworkRow, error) {
@@ -96,8 +94,7 @@ func (q *Queries) GetBannedUsersInNetwork(ctx context.Context, networkID snowfla
&i.User.Description,
&i.User.IsPublicDM,
&i.User.IsDeleted,
&i.BannedAt,
&i.Reason,
&i.BanReason,
); err != nil {
return nil, err
}
@@ -176,7 +173,7 @@ SELECT
users_networks.is_muted
FROM users_networks
JOIN users ON users.id = users_networks.user_id
WHERE users_networks.network_id = ?
WHERE users_networks.network_id = ? AND is_member = true
`
type GetUsersInNetworkRow struct {

View File

@@ -117,7 +117,7 @@ RETURNING id, name, public_key, description, is_public_dm, is_deleted
`
type SetUserDescriptionParams struct {
Description *string
Description string
ID snowflake.ID
}

View File

@@ -1,67 +0,0 @@
package packet
import (
"github.com/kyren223/eko/internal/data"
"github.com/kyren223/eko/pkg/snowflake"
)
type ErrorMessage struct {
Error string `msgpack:"error"`
}
func (m *ErrorMessage) Type() PacketType {
return PacketError
}
type SendMessage struct {
ReceiverID *snowflake.ID
FrequencyID *snowflake.ID
Content string
}
func (m *SendMessage) Type() PacketType {
return PacketSendMessage
}
type PushedMessages struct {
Messages []data.Message
}
func (m *PushedMessages) Type() PacketType {
return PacketPushedMessages
}
type Messages struct {
Messages []data.Message
}
func (m *Messages) Type() PacketType {
return PacketMessages
}
type GetMessagesRange struct {
FrequencyID *snowflake.ID
ReceiverID *snowflake.ID
From *int64
To *int64
}
func (m *GetMessagesRange) Type() PacketType {
return PacketGetMessageRange
}
type GetUserByID struct {
UserID snowflake.ID
}
func (m *GetUserByID) Type() PacketType {
return PacketGetUserById
}
type Users struct {
Users []data.User
}
func (m *Users) Type() PacketType {
return PacketUsers
}

View File

@@ -51,47 +51,34 @@ type PacketType uint8
const (
PacketError PacketType = iota
PacketCreateNetwork
PacketUpdateNetwork
PacketTransferNetwork
PacketDeleteNetwork
PacketSetNetworkUser
PacketNetworksInfo
PacketCreateFrequency
PacketUpdateFrequency
PacketDeleteFrequency
PacketSwapFrequencies
PacketSendMessage
PacketPushedMessages
PacketGetMessageRange
PacketMessages
PacketGetUserById
PacketUsers
PacketEditMessage
PacketDeleteMessage
PacketRequestMessages
PacketMessagesInfo
PacketMax
)
func (t PacketType) String() string {
switch t {
case PacketError:
return "PacketError"
case PacketSendMessage:
return "PacketSendMessage"
case PacketPushedMessages:
return "PacketPushedMessages"
case PacketGetMessageRange:
return "PacketGetMessageRange"
case PacketMessages:
return "PacketMessages"
case PacketGetUserById:
return "PacketGetUserById"
case PacketUsers:
return "PacketUsers"
default:
return fmt.Sprintf("PacketInvalidType(%v)", byte(t))
}
func Init() {
assert.Assert(PacketMax <= 64, "packet types exceeded allowed limit of 64 types")
}
func (e PacketType) IsSupported() bool {
return e <= PacketUsers
}
// True for all packets that a server may push passively to the client.
func (e PacketType) IsPush() bool {
switch e {
case PacketPushedMessages:
return true
default:
return false
}
return e < PacketMax
}
const (
@@ -166,7 +153,7 @@ func (p Packet) Payload() []byte {
}
func (p Packet) String() string {
return fmt.Sprintf("Packet(v%v %v %v [%v bytes...])", p.Version(), p.Encoding().String(), p.Type().String(), p.PayloadLength())
return fmt.Sprintf("Packet(v%v t%v %v [%v bytes...])", p.Version(), p.Encoding().String(), p.Type(), p.PayloadLength())
}
func (p Packet) Into(writer io.Writer) (int, error) {
@@ -196,21 +183,39 @@ func (p Packet) DecodedPayload() (Payload, error) {
var payload Payload
switch p.Type() {
case PacketError:
payload = &ErrorMessage{}
case PacketPushedMessages:
payload = &PushedMessages{}
payload = &Error{}
case PacketCreateFrequency:
payload = &CreateFrequency{}
case PacketCreateNetwork:
payload = &CreateNetwork{}
case PacketDeleteFrequency:
payload = &DeleteFrequency{}
case PacketDeleteMessage:
payload = &DeleteMessage{}
case PacketDeleteNetwork:
payload = &DeleteNetwork{}
case PacketEditMessage:
payload = &EditMessage{}
case PacketMessagesInfo:
payload = &MessagesInfo{}
case PacketNetworksInfo:
payload = &NetworksInfo{}
case PacketRequestMessages:
payload = &RequestMessages{}
case PacketSendMessage:
payload = &SendMessage{}
case PacketGetMessageRange:
payload = &GetMessagesRange{}
case PacketMessages:
payload = &Messages{}
case PacketGetUserById:
payload = &GetUserByID{}
case PacketUsers:
payload = &Users{}
case PacketSetNetworkUser:
payload = &SetNetworkUser{}
case PacketSwapFrequencies:
payload = &SwapFrequencies{}
case PacketTransferNetwork:
payload = &TransferNetwork{}
case PacketUpdateFrequency:
payload = &UpdateFrequency{}
case PacketUpdateNetwork:
payload = &UpdateNetwork{}
default:
assert.Never("packet type of a packet struct must always be valid")
assert.Never("unexpected packet.PacketType", "type", p.Type())
}
err := p.DecodePayloadInto(payload)
return payload, err

162
internal/packet/types.go Normal file
View File

@@ -0,0 +1,162 @@
package packet
import (
"github.com/kyren223/eko/internal/data"
"github.com/kyren223/eko/pkg/snowflake"
)
type Error struct {
Error string
}
func (m *Error) Type() PacketType {
return PacketError
}
type CreateNetwork struct {
Name string
Icon string
BgHexColor string
FgHexColor string
IsPublic bool
}
func (m *CreateNetwork) Type() PacketType {
return PacketCreateNetwork
}
type UpdateNetwork struct {
Network snowflake.ID
CreateNetwork
}
func (m *UpdateNetwork) Type() PacketType {
return PacketUpdateNetwork
}
type TransferNetwork struct {
Network snowflake.ID
User snowflake.ID
}
func (m *TransferNetwork) Type() PacketType {
return PacketTransferNetwork
}
type DeleteNetwork struct {
Network snowflake.ID
}
func (m *DeleteNetwork) Type() PacketType {
return PacketDeleteNetwork
}
type SetNetworkUser struct {
Network snowflake.ID
User snowflake.ID
Member *bool
Admin *bool
Muted *bool
Banned *bool
BanReason *string
}
func (m *SetNetworkUser) Type() PacketType {
return PacketSetNetworkUser
}
type NetworksInfo struct {
Networks []struct {
Network data.Network
Frequencies []data.Frequency
Members []data.User
}
}
func (m *NetworksInfo) Type() PacketType {
return PacketNetworksInfo
}
type CreateFrequency struct {
Network snowflake.ID
Name string
HexColor string
Perms int
}
func (m *CreateFrequency) Type() PacketType {
return PacketCreateFrequency
}
type UpdateFrequency struct {
Frequency snowflake.ID
Name string
HexColor string
Perms byte
}
func (m *UpdateFrequency) Type() PacketType {
return PacketUpdateFrequency
}
type DeleteFrequency struct {
Frequency snowflake.ID
}
func (m *DeleteFrequency) Type() PacketType {
return PacketDeleteFrequency
}
type SwapFrequencies struct {
Network snowflake.ID
Pos1 int
Pos2 int
}
func (m *SwapFrequencies) Type() PacketType {
return PacketSwapFrequencies
}
type SendMessage struct {
ReceiverID *snowflake.ID
FrequencyID *snowflake.ID
Content string
}
func (m *SendMessage) Type() PacketType {
return PacketSendMessage
}
type EditMessage struct {
Message snowflake.ID
Content string
}
func (m *EditMessage) Type() PacketType {
return PacketEditMessage
}
type DeleteMessage struct {
Message snowflake.ID
}
func (m *DeleteMessage) Type() PacketType {
return PacketDeleteMessage
}
type RequestMessages struct {
ReceiverID *snowflake.ID
FrequencyID *snowflake.ID
}
func (m *RequestMessages) Type() PacketType {
return PacketRequestMessages
}
type MessagesInfo struct {
Messages []data.Message
}
func (m *MessagesInfo) Type() PacketType {
return PacketMessagesInfo
}

View File

@@ -3,7 +3,7 @@ CREATE TABLE messages (
id INTEGER PRIMARY KEY,
sender_id INT NOT NULL REFERENCES users (id),
content TEXT NOT NULL,
edited BOOLEAN NOT NULL CHECK (edited IN (0, 1)) DEFAULT 0,
edited BOOLEAN NOT NULL CHECK (edited IN (false, true)) DEFAULT false,
frequency_id INT REFERENCES frequencies (id) ON DELETE CASCADE,
receiver_id INT REFERENCES users (id),
@@ -18,9 +18,9 @@ CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
public_key BLOB NOT NULL UNIQUE,
description TEXT,
is_public_dm BOOLEAN NOT NULL CHECK (is_public_dm IN (0, 1)) DEFAULT 1,
is_deleted BOOLEAN NOT NULL CHECK (is_deleted IN (0, 1)) DEFAULT 0
description TEXT NOT NULL,
is_public_dm BOOLEAN NOT NULL CHECK (is_public_dm IN (false, true)) DEFAULT true,
is_deleted BOOLEAN NOT NULL CHECK (is_deleted IN (false, true)) DEFAULT false
);
CREATE TABLE networks (
@@ -30,7 +30,7 @@ CREATE TABLE networks (
icon TEXT NOT NULL,
bg_hex_color TEXT NOT NULL,
fg_hex_color TEXT NOT NULL,
is_public BOOLEAN NOT NULL CHECK (is_public IN (0, 1))
is_public BOOLEAN NOT NULL CHECK (is_public IN (false, true))
);
CREATE TABLE frequencies (
@@ -39,7 +39,7 @@ CREATE TABLE frequencies (
name TEXT NOT NULL,
hex_color TEXT,
perms INT NOT NULL CHECK (perms IN (0, 1, 2)),
-- 0 rw admin | 1 r all w admin | 2 rw all
-- 0 no access | 1 read | 2 read & write
position INT NOT NULL
);
@@ -47,8 +47,11 @@ CREATE TABLE users_networks (
user_id INT NOT NULL REFERENCES users (id),
network_id INT NOT NULL REFERENCES networks (id) ON DELETE CASCADE,
joined_at TEXT NOT NULL DEFAULT current_timestamp,
is_admin BOOLEAN NOT NULL CHECK (is_admin IN (0, 1)) DEFAULT 0,
is_muted BOOLEAN NOT NULL CHECK (is_muted IN (0, 1)) DEFAULT 0,
is_member BOOLEAN NOT NULL CHECK (is_member IN (false, true)) DEFAULT true,
is_admin BOOLEAN NOT NULL CHECK (is_admin IN (false, true)) DEFAULT false,
is_muted BOOLEAN NOT NULL CHECK (is_muted IN (false, true)) DEFAULT false,
is_banned BOOLEAN NOT NULL CHECK (is_banned IN (false, true)) DEFAULT false,
ban_reason TEXT,
PRIMARY KEY (user_id, network_id)
);
@@ -65,18 +68,10 @@ CREATE TABLE user_blocked_users (
PRIMARY KEY (blocker_user_id, blocked_user_id)
);
CREATE TABLE network_banned_users (
network_id INT NOT NULL REFERENCES networks (id) ON DELETE CASCADE,
banned_user_id INT NOT NULL REFERENCES users (id),
banned_at TEXT NOT NULL DEFAULT current_timestamp,
reason TEXT,
PRIMARY KEY (network_id, banned_user_id)
);
CREATE INDEX idx_network_name ON networks (name) WHERE is_public = 1;
CREATE INDEX idx_network_name ON networks (name) WHERE is_public = true;
CREATE INDEX idx_frequency_network ON frequencies (network_id);
CREATE INDEX idx_blocked_by_user ON user_blocked_users (blocker_user_id);
CREATE INDEX idx_banned_by_network ON network_banned_users (network_id);
CREATE INDEX idx_banned_by_network ON users_networks (network_id) WHERE is_banned = true;
CREATE INDEX idx_direct_messages ON messages (sender_id, receiver_id);
CREATE INDEX idx_frequency_messages ON messages (frequency_id);

View File

@@ -19,11 +19,10 @@ RETURNING *;
-- name: GetBannedUsersInNetwork :many
SELECT
sqlc.embed(users),
network_banned_users.banned_at,
network_banned_users.reason
FROM network_banned_users
JOIN users ON users.id = network_banned_users.banned_user_id
WHERE network_banned_users.network_id = ?;
users_networks.ban_reason
FROM users_networks
JOIN users ON users.id = users_networks.user_id
WHERE users_networks.network_id = ?;
-- name: GetUsersInNetwork :many
SELECT
@@ -33,7 +32,7 @@ SELECT
users_networks.is_muted
FROM users_networks
JOIN users ON users.id = users_networks.user_id
WHERE users_networks.network_id = ?;
WHERE users_networks.network_id = ? AND is_member = true;
-- name: SetNetworkName :one
UPDATE networks SET