diff options
| -rw-r--r-- | cmd/client/main.go | 1 | ||||
| -rw-r--r-- | cmd/server/main.go | 5 | ||||
| -rw-r--r-- | internal/client/api/api.go | 23 | ||||
| -rw-r--r-- | internal/client/client.go | 6 | ||||
| -rw-r--r-- | internal/server/api/api.go | 35 | ||||
| -rw-r--r-- | internal/server/api/database.go | 35 |
6 files changed, 81 insertions, 24 deletions
diff --git a/cmd/client/main.go b/cmd/client/main.go index de800e7..61ea570 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -16,5 +16,4 @@ func main() { log.SetOutput(logFile) client.Run() - } diff --git a/cmd/server/main.go b/cmd/server/main.go index 4b504f6..0552c41 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -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) } + diff --git a/internal/client/api/api.go b/internal/client/api/api.go index 56cf054..9cfa1d4 100644 --- a/internal/client/api/api.go +++ b/internal/client/api/api.go @@ -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()) } } diff --git a/internal/client/client.go b/internal/client/client.go index 598772b..b091343 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -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{} diff --git a/internal/server/api/api.go b/internal/server/api/api.go index cf072f3..8f9e6c6 100644 --- a/internal/server/api/api.go +++ b/internal/server/api/api.go @@ -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, - } - messages = append(messages, message) - - // TODO: broadcast message - payload := &packet.Messages{Messages: messages} - pkt := packet.NewPacket(packet.NewMsgPackEncoder(payload)) - sess.WriteQueue <- pkt + 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"} + } - return packet.NewOkMessage() + return &packet.Messages{Messages: []data.Message{message}} } -var messages []data.Message +func GetMessages(ctx context.Context, request *packet.GetMessagesRange) packet.Payload { +} diff --git a/internal/server/api/database.go b/internal/server/api/database.go new file mode 100644 index 0000000..7057393 --- /dev/null +++ b/internal/server/api/database.go @@ -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") +} |
