feat: add setup for SQL

This commit is contained in:
Kyren223
2024-10-27 17:04:08 +02:00
parent 9a1030a579
commit 31e3778061
16 changed files with 545 additions and 64 deletions

2
go.mod
View File

@@ -10,7 +10,6 @@ require (
)
require (
github.com/ProtonMail/gopenpgp/v3 v3.0.0-beta.2-proton // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/x/ansi v0.2.3 // indirect
@@ -24,6 +23,7 @@ require (
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/stretchr/testify v1.7.0 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect

10
go.sum
View File

@@ -1,7 +1,5 @@
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/ProtonMail/gopenpgp/v3 v3.0.0-beta.2-proton h1:XFu8VgaGnb5MGOnwUr/l25HGLwfI/XFz12yTb3qhUYQ=
github.com/ProtonMail/gopenpgp/v3 v3.0.0-beta.2-proton/go.mod h1:TBpqWZ9IzA7g3TEzNA9Fwv/nA/eYpjcvYQBq+FX+tE4=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
@@ -39,9 +37,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
@@ -52,8 +50,8 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -135,12 +135,12 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case *packet.Messages:
slices.SortFunc(msg.Messages, func(a, b data.Message) int {
return a.CmpTimestamp(b)
if a.ID - b.ID < 0 { return -1 } else { return 1 }
})
m.messages = []string{}
for _, message := range msg.Messages {
m.messages = append(m.messages, message.Contents)
m.messages = append(m.messages, message.Content)
}
m.viewport.SetContent(strings.Join(m.messages, "\n"))

View File

@@ -1,55 +0,0 @@
package data
import (
"github.com/kyren223/eko/pkg/snowflake"
"github.com/kyren223/eko/pkg/utils"
)
// Represents an Eko Network, equivalent to a "discord server".
type Network struct {
id snowflake.ID
name string
frequencies []snowflake.ID
}
// Represents an Eko Frequency, equivalent to a "discord channel" within a "discord server".
type Frequency struct {
id snowflake.ID
name string
}
// Represents an Eko Signal, equivalent to a "discord message" between only 2 people.
type Signal struct {
userId1 snowflake.ID
userId2 snowflake.ID
}
// Represents a message
type Message struct {
Id snowflake.ID
SenderId snowflake.ID
FrequencyId snowflake.ID
NetworkId snowflake.ID
Contents string
}
func (a Message) CmpTimestamp(b Message) int {
cmpTime := a.Id.Time() - b.Id.Time()
if cmpTime != 0 {
return int(utils.Clamp(cmpTime, -1, 1))
}
cmpStep := a.Id.Step() - b.Id.Step()
if cmpStep != 0 {
return int(utils.Clamp(cmpStep, -1, 1))
}
cmpNode := a.Id.Node() - b.Id.Node()
if cmpNode != 0 {
return int(utils.Clamp(cmpNode, -1, 1))
}
return 0
}
// Represents an Eko User
type User struct {
id snowflake.ID
}

31
internal/data/db.go Normal file
View File

@@ -0,0 +1,31 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
package data
import (
"context"
"database/sql"
)
type DBTX interface {
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
PrepareContext(context.Context, string) (*sql.Stmt, error)
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
return &Queries{
db: tx,
}
}

View File

@@ -0,0 +1,63 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: frequencies.sql
package data
import (
"context"
"github.com/kyren223/eko/pkg/snowflake"
)
const createFrequency = `-- name: CreateFrequency :one
INSERT INTO frequencies (
id, network_id, name
) VALUES (
?, ?, ?
)
RETURNING id, network_id, name
`
type CreateFrequencyParams struct {
ID snowflake.ID
NetworkID snowflake.ID
Name string
}
func (q *Queries) CreateFrequency(ctx context.Context, arg CreateFrequencyParams) (Frequency, error) {
row := q.db.QueryRowContext(ctx, createFrequency, arg.ID, arg.NetworkID, arg.Name)
var i Frequency
err := row.Scan(&i.ID, &i.NetworkID, &i.Name)
return i, err
}
const getNetworkFrequencies = `-- name: GetNetworkFrequencies :many
SELECT id, network_id, name FROM frequencies
WHERE network_id = ?
ORDER BY id
`
func (q *Queries) GetNetworkFrequencies(ctx context.Context, networkID snowflake.ID) ([]Frequency, error) {
rows, err := q.db.QueryContext(ctx, getNetworkFrequencies, networkID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Frequency
for rows.Next() {
var i Frequency
if err := rows.Scan(&i.ID, &i.NetworkID, &i.Name); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}

View File

@@ -0,0 +1,114 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: messages.sql
package data
import (
"context"
"github.com/kyren223/eko/pkg/snowflake"
)
const createDirectMessage = `-- name: CreateDirectMessage :one
INSERT INTO messages (
id, content, sender_id, receiver_id
) VALUES (
?, ?, ?, ?
)
RETURNING id, sender_id, content, frequency_id, receiver_id
`
type CreateDirectMessageParams struct {
ID snowflake.ID
Content string
SenderID snowflake.ID
ReceiverID snowflake.ID
}
func (q *Queries) CreateDirectMessage(ctx context.Context, arg CreateDirectMessageParams) (Message, error) {
row := q.db.QueryRowContext(ctx, createDirectMessage,
arg.ID,
arg.Content,
arg.SenderID,
arg.ReceiverID,
)
var i Message
err := row.Scan(
&i.ID,
&i.SenderID,
&i.Content,
&i.FrequencyID,
&i.ReceiverID,
)
return i, err
}
const createMessage = `-- name: CreateMessage :one
INSERT INTO messages (
id, content, sender_id, frequency_id
) VALUES (
?, ?, ?, ?
)
RETURNING id, sender_id, content, frequency_id, receiver_id
`
type CreateMessageParams struct {
ID snowflake.ID
Content string
SenderID snowflake.ID
FrequencyID snowflake.ID
}
func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) (Message, error) {
row := q.db.QueryRowContext(ctx, createMessage,
arg.ID,
arg.Content,
arg.SenderID,
arg.FrequencyID,
)
var i Message
err := row.Scan(
&i.ID,
&i.SenderID,
&i.Content,
&i.FrequencyID,
&i.ReceiverID,
)
return i, err
}
const listMessages = `-- name: ListMessages :many
SELECT id, sender_id, content, frequency_id, receiver_id FROM messages
ORDER BY id
`
func (q *Queries) ListMessages(ctx context.Context) ([]Message, error) {
rows, err := q.db.QueryContext(ctx, listMessages)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Message
for rows.Next() {
var i Message
if err := rows.Scan(
&i.ID,
&i.SenderID,
&i.Content,
&i.FrequencyID,
&i.ReceiverID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}

41
internal/data/models.go Normal file
View File

@@ -0,0 +1,41 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
package data
import (
"crypto/ed25519"
"github.com/kyren223/eko/pkg/snowflake"
)
type Frequency struct {
ID snowflake.ID
NetworkID snowflake.ID
Name string
}
type Message struct {
ID snowflake.ID
SenderID snowflake.ID
Content string
FrequencyID snowflake.ID
ReceiverID snowflake.ID
}
type Network struct {
ID snowflake.ID
Name string
OwnerID snowflake.ID
}
type User struct {
ID snowflake.ID
Name string
PublicKey ed25519.PublicKey
}
type UsersNetwork struct {
UserID snowflake.ID
NetworkID snowflake.ID
}

View File

@@ -0,0 +1,74 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: networks.sql
package data
import (
"context"
"github.com/kyren223/eko/pkg/snowflake"
)
const createNetwork = `-- name: CreateNetwork :one
INSERT INTO networks (
id, name, owner_id
) VALUES (
?, ?, ?
)
RETURNING id, name, owner_id
`
type CreateNetworkParams struct {
ID snowflake.ID
Name string
OwnerID snowflake.ID
}
func (q *Queries) CreateNetwork(ctx context.Context, arg CreateNetworkParams) (Network, error) {
row := q.db.QueryRowContext(ctx, createNetwork, arg.ID, arg.Name, arg.OwnerID)
var i Network
err := row.Scan(&i.ID, &i.Name, &i.OwnerID)
return i, err
}
const getNetwork = `-- name: GetNetwork :one
SELECT id, name, owner_id FROM networks
WHERE id = ?
`
func (q *Queries) GetNetwork(ctx context.Context, id snowflake.ID) (Network, error) {
row := q.db.QueryRowContext(ctx, getNetwork, id)
var i Network
err := row.Scan(&i.ID, &i.Name, &i.OwnerID)
return i, err
}
const listNetworks = `-- name: ListNetworks :many
SELECT id, name, owner_id FROM networks
ORDER BY id
`
func (q *Queries) ListNetworks(ctx context.Context) ([]Network, error) {
rows, err := q.db.QueryContext(ctx, listNetworks)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Network
for rows.Next() {
var i Network
if err := rows.Scan(&i.ID, &i.Name, &i.OwnerID); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}

View File

@@ -0,0 +1,84 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.27.0
// source: users.sql
package data
import (
"context"
"crypto/ed25519"
"github.com/kyren223/eko/pkg/snowflake"
)
const createUser = `-- name: CreateUser :one
INSERT INTO users (
id, name, public_key
) VALUES (
?, 'User' || abs(random()) % 1000000, ?
)
RETURNING id, name, public_key
`
type CreateUserParams struct {
ID snowflake.ID
PublicKey ed25519.PublicKey
}
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) {
row := q.db.QueryRowContext(ctx, createUser, arg.ID, arg.PublicKey)
var i User
err := row.Scan(&i.ID, &i.Name, &i.PublicKey)
return i, err
}
const getUser = `-- name: GetUser :one
SELECT id, name, public_key FROM users
WHERE id = ?
`
func (q *Queries) GetUser(ctx context.Context, id snowflake.ID) (User, error) {
row := q.db.QueryRowContext(ctx, getUser, id)
var i User
err := row.Scan(&i.ID, &i.Name, &i.PublicKey)
return i, err
}
const setUserName = `-- name: SetUserName :one
UPDATE users SET
name = ?
WHERE id = ?
RETURNING id, name, public_key
`
type SetUserNameParams struct {
Name string
ID snowflake.ID
}
func (q *Queries) SetUserName(ctx context.Context, arg SetUserNameParams) (User, error) {
row := q.db.QueryRowContext(ctx, setUserName, arg.Name, arg.ID)
var i User
err := row.Scan(&i.ID, &i.Name, &i.PublicKey)
return i, err
}
const setUserPublicKey = `-- name: SetUserPublicKey :one
UPDATE users SET
public_key = ?
WHERE id = ?
RETURNING id, name, public_key
`
type SetUserPublicKeyParams struct {
PublicKey ed25519.PublicKey
ID snowflake.ID
}
func (q *Queries) SetUserPublicKey(ctx context.Context, arg SetUserPublicKeyParams) (User, error) {
row := q.db.QueryRowContext(ctx, setUserPublicKey, arg.PublicKey, arg.ID)
var i User
err := row.Scan(&i.ID, &i.Name, &i.PublicKey)
return i, err
}

View File

@@ -0,0 +1,45 @@
-- +goose Up
CREATE TABLE messages (
id INTEGER PRIMARY KEY,
sender_id INT NOT NULL REFERENCES users (id),
content TEXT NOT NULL,
frequency_id INT REFERENCES frequencies (id),
receiver_id INT REFERENCES users (id),
CHECK (
(frequency_id IS NOT NULL AND receiver_id IS NULL) OR
(frequency_id IS NULL AND receiver_id IS NOT NULL)
)
);
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
public_key BLOB NOT NULL
);
CREATE TABLE networks (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
owner_id INT NOT NULL REFERENCES users (id)
);
CREATE TABLE frequencies (
id INTEGER PRIMARY KEY,
network_id INT NOT NULL REFERENCES networks (id),
name TEXT NOT NULL
);
CREATE TABLE users_networks (
user_id INT NOT NULL REFERENCES users (id),
network_id INT NOT NULL REFERENCES networks (id),
PRIMARY KEY (user_id, network_id)
);
-- +goose Down
DROP TABLE messages;
DROP TABLE users;
DROP TABLE networks;
DROP TABLE frequencies;
DROP TABLE users_networks;

12
query/frequencies.sql Normal file
View File

@@ -0,0 +1,12 @@
-- name: GetNetworkFrequencies :many
SELECT * FROM frequencies
WHERE network_id = ?
ORDER BY id;
-- name: CreateFrequency :one
INSERT INTO frequencies (
id, network_id, name
) VALUES (
?, ?, ?
)
RETURNING *;

19
query/messages.sql Normal file
View File

@@ -0,0 +1,19 @@
-- name: ListMessages :many
SELECT * FROM messages
ORDER BY id;
-- name: CreateDirectMessage :one
INSERT INTO messages (
id, content, sender_id, receiver_id
) VALUES (
?, ?, ?, ?
)
RETURNING *;
-- name: CreateMessage :one
INSERT INTO messages (
id, content, sender_id, frequency_id
) VALUES (
?, ?, ?, ?
)
RETURNING *;

15
query/networks.sql Normal file
View File

@@ -0,0 +1,15 @@
-- name: ListNetworks :many
SELECT * FROM networks
ORDER BY id;
-- name: GetNetwork :one
SELECT * FROM networks
WHERE id = ?;
-- name: CreateNetwork :one
INSERT INTO networks (
id, name, owner_id
) VALUES (
?, ?, ?
)
RETURNING *;

23
query/users.sql Normal file
View File

@@ -0,0 +1,23 @@
-- name: GetUser :one
SELECT * FROM users
WHERE id = ?;
-- name: CreateUser :one
INSERT INTO users (
id, name, public_key
) VALUES (
?, 'User' || abs(random()) % 1000000, ?
)
RETURNING *;
-- name: SetUserName :one
UPDATE users SET
name = ?
WHERE id = ?
RETURNING *;
-- name: SetUserPublicKey :one
UPDATE users SET
public_key = ?
WHERE id = ?
RETURNING *;

17
sqlc.yml Normal file
View File

@@ -0,0 +1,17 @@
version: "2"
sql:
- engine: "sqlite"
queries: "./query/"
schema: "./migrations"
gen:
go:
package: "data"
out: "./internal/data/"
emit_pointers_for_null_types: true
overrides:
- column: "*.id"
go_type: "github.com/kyren223/eko/pkg/snowflake.ID"
- column: "*.*_id"
go_type: "github.com/kyren223/eko/pkg/snowflake.ID"
- column: "users.public_key"
go_type: "crypto/ed25519.PublicKey"