diff --git a/client/message.go b/client/message.go index 2853eca..c10ae11 100644 --- a/client/message.go +++ b/client/message.go @@ -3,8 +3,9 @@ package client import "forge.redroom.link/yves/meowlib" type InternalUserMessage struct { - message *meowlib.UserMessage - dbid int64 + Message *meowlib.UserMessage + Dbfile string + Dbid int64 } func ProcessOutboundTextMessage(peer *Peer, text string, srv *Server) ([]byte, error) { diff --git a/client/storage.go b/client/messagestorage.go similarity index 75% rename from client/storage.go rename to client/messagestorage.go index 32bac11..d0d62e4 100644 --- a/client/storage.go +++ b/client/messagestorage.go @@ -73,8 +73,56 @@ func StoreMessage(peer *Peer, usermessage *meowlib.UserMessage, password string) return nil } -// Get last messages from a peer -func GetLastMessages(peer *Peer, inAppMsgCount int, lastDbId int, wantMore int, password string) ([]InternalUserMessage, error) { +// Get new messages from a peer +func GetNewMessages(peer *Peer, lastDbId int, password string) ([]InternalUserMessage, error) { + var messages []InternalUserMessage + fileidx := len(peer.DbIds) - 1 + // There fileidx should provide the db that we need (unless wantMore overlaps the next DB) + db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, peer.DbIds[fileidx]+GetConfig().DbSuffix)) // Open the created SQLite File + defer db.Close() + // if it's first app query, it won't hold a lastIndex, so let's start from end + if lastDbId == 0 { + lastDbId = math.MaxInt64 + } + stm, err := db.Prepare("SELECT id, m FROM message WHERE id > ? ORDER BY id DESC") + if err != nil { + return nil, err + } + defer stm.Close() + rows, err := stm.Query(lastDbId) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var ium InternalUserMessage + var um meowlib.UserMessage + var id int64 + var m []byte + err = rows.Scan(&id, &m) + if err != nil { + return nil, err + } + decdata, err := meowlib.SymDecrypt(password, m) + if err != nil { + return nil, err + } + err = proto.Unmarshal(decdata, &um) + if err != nil { + return nil, err + } + ium.Dbid = id + ium.Dbfile = peer.DbIds[fileidx] + ium.Message = &um + messages = append(messages, ium) + } + // TODO DB overlap + return messages, nil +} + +// Get old messages from a peer +func GetMessagesHistory(peer *Peer, inAppMsgCount int, lastDbId int, wantMore int, password string) ([]InternalUserMessage, error) { var messages []InternalUserMessage fileidx := len(peer.DbIds) - 1 // initialize count with last db message count @@ -129,8 +177,9 @@ func GetLastMessages(peer *Peer, inAppMsgCount int, lastDbId int, wantMore int, if err != nil { return nil, err } - ium.dbid = id - ium.message = &um + ium.Dbid = id + ium.Dbfile = peer.DbIds[fileidx] + ium.Message = &um messages = append(messages, ium) } // TODO DB overlap diff --git a/client/storage_test.go b/client/messagestorage_test.go similarity index 84% rename from client/storage_test.go rename to client/messagestorage_test.go index b094ab3..32f5e1a 100644 --- a/client/storage_test.go +++ b/client/messagestorage_test.go @@ -18,13 +18,13 @@ func TestStoreMessage(t *testing.T) { if err != nil { log.Fatal(err) } - messages, err := GetLastMessages(&id.Peers[0], 0, 0, 10, GetConfig().memoryPassword) + messages, err := GetMessagesHistory(&id.Peers[0], 0, 0, 10, GetConfig().memoryPassword) if err != nil { log.Fatal(err) } // Checks assert.Equal(t, len(messages), 1, "not 1 message") - assert.Equal(t, messages[0].message.Data, um.Data, "not 1 message") + assert.Equal(t, messages[0].Message.Data, um.Data, "not 1 message") // Cleanup if exists("test.id") { os.Remove("test.id") @@ -50,7 +50,7 @@ func TestManyStoreMessage(t *testing.T) { log.Fatal(err) } } - messages, err := GetLastMessages(&id.Peers[0], 0, 0, 10, GetConfig().memoryPassword) + messages, err := GetMessagesHistory(&id.Peers[0], 0, 0, 10, GetConfig().memoryPassword) if err != nil { log.Fatal(err) } diff --git a/client/peer.go b/client/peer.go index 8a50f87..c247c2f 100644 --- a/client/peer.go +++ b/client/peer.go @@ -273,19 +273,31 @@ func (p *Peer) SetDbPassword(password string) { } func (p *Peer) GetDbPassword() string { + if p.dbPassword == "" { + return GetConfig().memoryPassword + } return p.dbPassword } -func (p *Peer) StoreMessage(msg []byte) { +func (p *Peer) StoreMessage(msg *meowlib.UserMessage) error { + return StoreMessage(p, msg, p.GetDbPassword()) +} + +func (p *Peer) UpdateMessage(msg InternalUserMessage) error { + return nil +} + +func (p *Peer) LoadLastMessages(alreadyLoadedCount int, oldestMessageId int, qty int) ([]InternalUserMessage, error) { + return GetMessagesHistory(p, alreadyLoadedCount, oldestMessageId, 1, p.GetDbPassword()) } -func (p *Peer) LoadMessage(uid string) { - +func (p *Peer) LoadNewMessages(lastMessageId int) ([]InternalUserMessage, error) { + return GetNewMessages(p, lastMessageId, p.GetDbPassword()) } -func (p *Peer) LoadLastMessages(qty int) { - +func (p *Peer) LoadMessage(uid string) (*InternalUserMessage, error) { + return nil, nil } func (p *Peer) GetLastMessageUuid(msg []byte) {