feat: client and server api changes to accomedate DB

This commit is contained in:
2024-11-02 13:14:03 +02:00
parent 7ad5f5aa60
commit c5064f6bbd
6 changed files with 81 additions and 24 deletions

View File

@@ -16,5 +16,4 @@ func main() {
log.SetOutput(logFile)
client.Run()
}

View File

@@ -8,6 +8,7 @@ import (
"syscall"
"github.com/kyren223/eko/internal/server"
"github.com/kyren223/eko/internal/server/api"
)
const port = 7223
@@ -20,6 +21,9 @@ func main() {
defer logFile.Close()
log.SetOutput(logFile)
api.ConnectToDatabase()
defer api.CloseDatabase()
server := server.NewServer(port)
ctx, cancel := context.WithCancel(context.Background())
@@ -33,3 +37,4 @@ func main() {
server.ListenAndServe(ctx)
}

View File

@@ -1,29 +1,38 @@
package api
import (
"errors"
"fmt"
"log"
tea "github.com/charmbracelet/bubbletea"
"github.com/kyren223/eko/internal/client/gateway"
"github.com/kyren223/eko/internal/data"
"github.com/kyren223/eko/internal/packet"
"github.com/kyren223/eko/pkg/assert"
)
type AppendMessage data.Message
func SendMessage(message string) tea.Cmd {
return func() tea.Msg {
log.Println("request SendMessage sent")
request := packet.SendMessage{Content: message}
responsePayload, ok := <-gateway.Send(&request)
response, ok := <-gateway.Send(&request)
if !ok {
log.Println("request timeout")
return ""
log.Println()
return errors.New("request timeout")
}
log.Println("request SendMessage received response")
response := responsePayload.(*packet.ErrorMessage)
assert.Assert(ok, "server should return an ErrorMessage response for a SendMessage request")
assert.Assert(response.IsOk(), "server should always return an OK if we didn't mess up")
return ""
switch response := response.(type) {
case *packet.ErrorMessage:
return errors.New(response.Error)
case *packet.Messages:
assert.Assert(len(response.Messages) == 1, "server must return only the one message that was sent")
return AppendMessage(response.Messages[0])
}
return fmt.Errorf("received invalid response from server: %v", response.Type())
}
}

View File

@@ -135,7 +135,11 @@ 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 {
if a.ID - b.ID < 0 { return -1 } else { return 1 }
if a.ID-b.ID < 0 {
return -1
} else {
return 1
}
})
m.messages = []string{}

View File

@@ -2,6 +2,7 @@ package api
import (
"context"
"log"
"strings"
"github.com/kyren223/eko/internal/data"
@@ -14,28 +15,32 @@ func SendMessage(ctx context.Context, request *packet.SendMessage) packet.Payloa
sess, ok := session.FromContext(ctx)
assert.Assert(ok, "context in process packet should always have a session")
if (request.ReceiverID != nil) != (request.FrequencyID != nil) {
return &packet.ErrorMessage{Error: "either receiver id or frequency id must exist"}
}
content := strings.TrimSpace(request.Content)
if content == "" {
return &packet.ErrorMessage{Error: "message content must not be blank"}
}
node := sess.Manager().Node()
message := data.Message{
Id: node.Generate(),
SenderId: sess.ID(),
FrequencyId: node.Generate(), // TODO: replace with actual ID
NetworkId: node.Generate(), // TODO: replace with actual ID
Contents: content,
queries := data.New(db)
message, err := queries.CreateMessage(ctx, data.CreateMessageParams{
ID: node.Generate(),
SenderID: sess.ID(),
Content: content,
FrequencyID: request.FrequencyID,
ReceiverID: request.ReceiverID,
})
if err != nil {
log.Println(sess.Addr(), "SendMessage database error:", err)
return &packet.ErrorMessage{Error: "internal server error"}
}
messages = append(messages, message)
// TODO: broadcast message
payload := &packet.Messages{Messages: messages}
pkt := packet.NewPacket(packet.NewMsgPackEncoder(payload))
sess.WriteQueue <- pkt
return packet.NewOkMessage()
return &packet.Messages{Messages: []data.Message{message}}
}
var messages []data.Message
func GetMessages(ctx context.Context, request *packet.GetMessagesRange) packet.Payload {
}

View File

@@ -0,0 +1,35 @@
package api
import (
"database/sql"
"log"
"github.com/kyren223/eko/pkg/assert"
)
var db *sql.DB
func ConnectToDatabase() {
db, err := sql.Open("sqlite3", "server.db")
assert.NoError(err, "DB should always be accessible")
assert.AddFlush(db)
log.Println("established connection with the database")
pragmas := []string{
"PRAGMA journal_mode = WAL;",
"PRAGMA synchronous = NORMAL;",
"PRAGMA temp_store = MEMORY;",
"PRAGMA mmap_size = 30000000000;",
}
for _, pragma := range pragmas {
_, err := db.Exec(pragma)
assert.NoError(err, "DB pragmas should always execute with no errors")
}
log.Println("database connection ready to be used")
}
func CloseDatabase() {
db.Close()
log.Println("connection with database closed")
}