summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--cmd/daemon/main.go15
-rw-r--r--go.mod5
-rw-r--r--go.sum2
-rw-r--r--server/message.go4
-rw-r--r--server/server.go6
-rw-r--r--server/storage.go12
-rw-r--r--storage/storage.go61
-rw-r--r--storage/storage_test.go7
9 files changed, 109 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..884e3de
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+test.db \ No newline at end of file
diff --git a/cmd/daemon/main.go b/cmd/daemon/main.go
index bad350f..242a45a 100644
--- a/cmd/daemon/main.go
+++ b/cmd/daemon/main.go
@@ -11,11 +11,15 @@ import (
"strings"
"go.rctt.net/solec/server"
+ "go.rctt.net/solec/storage"
+
+ _ "github.com/mattn/go-sqlite3"
)
var (
cmds = map[string]func(args []string){
"broadcast": sendBroadcast,
+ "exit": exit,
}
serv *server.Server
)
@@ -28,7 +32,12 @@ func main() {
name := flag.String("n", "localhost", "server name")
flag.Parse()
- serv = server.NewServer(*addr, *name)
+ db, err := storage.InitDb("test.db")
+ if err != nil {
+ panic(err)
+ }
+
+ serv = server.NewServer(*addr, *name, db)
serv.AddChannel("test")
go func() {
@@ -64,3 +73,7 @@ func sendBroadcast(args []string) {
msg := strings.Join(args[0:], " ")
serv.SendBroadcast(msg)
}
+
+func exit(args []string) {
+ os.Exit(0)
+}
diff --git a/go.mod b/go.mod
index 9cb1eb8..6e83f85 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,7 @@ module go.rctt.net/solec
go 1.26.1
-require github.com/google/go-cmp v0.7.0
+require (
+ github.com/google/go-cmp v0.7.0
+ github.com/mattn/go-sqlite3 v1.14.44
+)
diff --git a/go.sum b/go.sum
index 40e761a..2c38b0c 100644
--- a/go.sum
+++ b/go.sum
@@ -1,2 +1,4 @@
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/mattn/go-sqlite3 v1.14.44 h1:3VSe+xafpbzsLbdr2AWlAZk9yRHiBhTBakioXaCKTF8=
+github.com/mattn/go-sqlite3 v1.14.44/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
diff --git a/server/message.go b/server/message.go
index 58f2908..11644dc 100644
--- a/server/message.go
+++ b/server/message.go
@@ -38,6 +38,10 @@ func (s *Server) handleMessage(sender net.Conn, msg core.Message) error {
return err
}
+ if err := s.storage.Write(msg); err != nil {
+ log.Println("cannot write to database", err)
+ }
+
if addr.Host == s.name {
return s.handleLocalMessage(sender, addr, msg)
}
diff --git a/server/server.go b/server/server.go
index ef2bb5f..74328a4 100644
--- a/server/server.go
+++ b/server/server.go
@@ -18,15 +18,17 @@ type Server struct {
usersMu sync.RWMutex
serversMu sync.RWMutex
channelsMu sync.RWMutex
+ storage Storage
}
-func NewServer(listenAddr string, name string) *Server {
+func NewServer(listenAddr string, name string, storage Storage) *Server {
return &Server{
listenAddr: listenAddr,
name: name,
users: make(map[string]User),
servers: make(map[string]RemoteServer),
channels: make(map[string]*Channel),
+ storage: storage,
}
}
@@ -50,7 +52,7 @@ func (s *Server) Start() error {
func (s *Server) AddChannel(name string) {
s.channelsMu.Lock()
- s.channelsMu.Unlock()
+ defer s.channelsMu.Unlock()
s.channels[name] = NewChannel(name)
log.Println("created channel", name)
}
diff --git a/server/storage.go b/server/storage.go
new file mode 100644
index 0000000..3473898
--- /dev/null
+++ b/server/storage.go
@@ -0,0 +1,12 @@
+package server
+
+import (
+ "time"
+
+ "go.rctt.net/solec/core"
+)
+
+type Storage interface {
+ Write(msg core.Message) (err error)
+ Read(channel string, since time.Time, num, offset int) (history []core.Message, err error)
+}
diff --git a/storage/storage.go b/storage/storage.go
new file mode 100644
index 0000000..9207761
--- /dev/null
+++ b/storage/storage.go
@@ -0,0 +1,61 @@
+package storage
+
+import (
+ "database/sql"
+ "fmt"
+ "time"
+
+ "go.rctt.net/solec/core"
+)
+
+type Database struct {
+ *sql.DB
+}
+
+const initSql = `
+ CREATE TABLE IF NOT EXISTS messages
+ (id INTEGER NOT NULL PRIMARY KEY, source STRING, target STRING, timestamp INT, content STRING);
+`
+
+func InitDb(path string) (*Database, error) {
+ db, err := sql.Open("sqlite3", path)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = db.Exec(initSql)
+ return &Database{db}, nil
+}
+
+func (db *Database) Write(msg core.Message) (err error) {
+ fmt.Println(msg.Timestamp)
+
+ _, err = db.Exec(
+ "INSERT INTO messages (source, target, timestamp, content) VALUES (?, ?, ?, ?);",
+ msg.Source, msg.Target, msg.Timestamp.Unix(), msg.Content,
+ )
+
+ return err
+}
+
+func (db *Database) Read(channel string, since time.Time, num int, offset int) (history []core.Message, err error) {
+ rows, err := db.Query(
+ "SELECT source, target, timestamp, content FROM messages WHERE timestamp > ? LIMIT ? OFFSET ?",
+ since.Unix(), num, offset,
+ )
+ defer rows.Close()
+
+ if err != nil {
+ return history, err
+ }
+
+ for rows.Next() {
+ var msg core.Message
+ if err := rows.Scan(&msg.Source, &msg.Target, &msg.Timestamp, &msg.Content); err != nil {
+ return history, err
+ }
+ history = append(history, msg)
+ }
+
+ return history, nil
+}
diff --git a/storage/storage_test.go b/storage/storage_test.go
new file mode 100644
index 0000000..7a72c1f
--- /dev/null
+++ b/storage/storage_test.go
@@ -0,0 +1,7 @@
+package storage
+
+import "testing"
+
+func TestStorage(t *testing.T) {
+
+}