This commit is contained in:
+225
-247
@@ -6,6 +6,7 @@ import (
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"forge.redroom.link/yves/meowlib"
|
||||
"github.com/google/uuid"
|
||||
@@ -13,71 +14,82 @@ import (
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func storeMessage(peer *Peer, usermessage *meowlib.UserMessage, filenames []string, password string) error {
|
||||
var dbid string
|
||||
cfg := GetConfig()
|
||||
identity := cfg.GetIdentity()
|
||||
// If no db/no ID create DB + Tablz
|
||||
// TODO : if file size > X new db
|
||||
if len(peer.DbIds) == 0 {
|
||||
dbid = uuid.NewString()
|
||||
peer.DbIds = []string{dbid}
|
||||
// One RWMutex per SQLite file path. Entries are never deleted (bounded by
|
||||
// peer count, which is small). RLock for reads, Lock for writes.
|
||||
var dbFileMu sync.Map
|
||||
|
||||
identity.Peers.StorePeer(peer)
|
||||
identity.CreateFolder()
|
||||
file, err := os.Create(filepath.Join(cfg.StoragePath, identity.Uuid, dbid+GetConfig().DbSuffix))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file.Close()
|
||||
sqliteDatabase, err := sql.Open("sqlite3", filepath.Join(cfg.StoragePath, identity.Uuid, dbid+GetConfig().DbSuffix))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sqliteDatabase.Close()
|
||||
err = createMessageTable(sqliteDatabase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sqliteDatabase.Close()
|
||||
} else {
|
||||
dbid = peer.DbIds[len(peer.DbIds)-1]
|
||||
}
|
||||
// Open Db
|
||||
db, err := sql.Open("sqlite3", filepath.Join(cfg.StoragePath, identity.Uuid, dbid+GetConfig().DbSuffix)) // Open the created SQLite File
|
||||
func getDbFileMutex(path string) *sync.RWMutex {
|
||||
v, _ := dbFileMu.LoadOrStore(path, &sync.RWMutex{})
|
||||
return v.(*sync.RWMutex)
|
||||
}
|
||||
|
||||
func withDbWrite(path string, fn func(*sql.DB) error) error {
|
||||
mu := getDbFileMutex(path)
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
db, err := sql.Open("sqlite3", path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
// Detach Files
|
||||
return fn(db)
|
||||
}
|
||||
|
||||
func withDbRead(path string, fn func(*sql.DB) error) error {
|
||||
mu := getDbFileMutex(path)
|
||||
mu.RLock()
|
||||
defer mu.RUnlock()
|
||||
db, err := sql.Open("sqlite3", path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
return fn(db)
|
||||
}
|
||||
|
||||
func dbPath(cfg *Config, identity *Identity, dbid string) string {
|
||||
return filepath.Join(cfg.StoragePath, identity.Uuid, dbid+cfg.DbSuffix)
|
||||
}
|
||||
|
||||
func storeMessage(peer *Peer, usermessage *meowlib.UserMessage, filenames []string, password string) error {
|
||||
cfg := GetConfig()
|
||||
identity := cfg.GetIdentity()
|
||||
|
||||
isNew := len(peer.DbIds) == 0
|
||||
var dbid string
|
||||
if isNew {
|
||||
dbid = uuid.NewString()
|
||||
peer.DbIds = []string{dbid}
|
||||
identity.Peers.StorePeer(peer)
|
||||
identity.CreateFolder()
|
||||
} else {
|
||||
dbid = peer.DbIds[len(peer.DbIds)-1]
|
||||
}
|
||||
|
||||
// Detach file attachments — no DB lock needed for file I/O.
|
||||
hiddenFilenames := []string{}
|
||||
if len(usermessage.Files) > 0 {
|
||||
secureDir := filepath.Join(cfg.StoragePath, identity.Uuid, "securefiles")
|
||||
if _, err := os.Stat(secureDir); os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(secureDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, f := range usermessage.Files {
|
||||
hiddenFilename := uuid.NewString()
|
||||
// Cypher file
|
||||
encData, err := meowlib.SymEncrypt(password, f.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(cfg.StoragePath, identity.Uuid, "securefiles")); os.IsNotExist(err) {
|
||||
err = os.MkdirAll(filepath.Join(cfg.StoragePath, identity.Uuid, "securefiles"), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
os.WriteFile(filepath.Join(cfg.StoragePath, identity.Uuid, "securefiles", hiddenFilename), encData, 0600)
|
||||
hiddenFilenames = append(hiddenFilenames, filepath.Join(cfg.StoragePath, identity.Uuid, "securefiles", hiddenFilename))
|
||||
// replace f.Data by uuid filename
|
||||
f.Data = []byte(filepath.Join(cfg.StoragePath, identity.Uuid, "securefiles", hiddenFilename))
|
||||
hidden := filepath.Join(secureDir, hiddenFilename)
|
||||
os.WriteFile(hidden, encData, 0600)
|
||||
hiddenFilenames = append(hiddenFilenames, hidden)
|
||||
f.Data = []byte(hidden)
|
||||
}
|
||||
}
|
||||
outbound := true
|
||||
if usermessage.From == peer.ContactPublicKey {
|
||||
outbound = false
|
||||
}
|
||||
// Convert UserMessage to DbMessage
|
||||
|
||||
outbound := usermessage.From != peer.ContactPublicKey
|
||||
dbm := UserMessageToDbMessage(outbound, usermessage, hiddenFilenames)
|
||||
// Encrypt message
|
||||
out, err := proto.Marshal(dbm)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -86,98 +98,94 @@ func storeMessage(peer *Peer, usermessage *meowlib.UserMessage, filenames []stri
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Insert message
|
||||
insertMessageSQL := `INSERT INTO message(m) VALUES (?) RETURNING ID`
|
||||
statement, err := db.Prepare(insertMessageSQL) // Prepare statement.
|
||||
|
||||
var id int64
|
||||
path := dbPath(cfg, identity, dbid)
|
||||
err = withDbWrite(path, func(db *sql.DB) error {
|
||||
// SQLite creates the file on first Open; create the table if new DB.
|
||||
if isNew {
|
||||
if err := createMessageTable(db); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
stmt, err := db.Prepare(`INSERT INTO message(m) VALUES (?) RETURNING ID`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := stmt.Exec(encData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id, err = result.LastInsertId()
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := statement.Exec(encData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ium := DbMessageToInternalUserMessage(id, dbid, dbm)
|
||||
peer.LastMessage = ium
|
||||
|
||||
peer.LastMessage = DbMessageToInternalUserMessage(id, dbid, dbm)
|
||||
identity.Peers.StorePeer(peer)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get new messages from a peer
|
||||
func loadNewMessages(peer *Peer, lastDbId int, password string) ([]*InternalUserMessage, error) {
|
||||
var messages []*InternalUserMessage
|
||||
cfg := GetConfig()
|
||||
identity := cfg.GetIdentity()
|
||||
// handle no db yet
|
||||
if len(peer.DbIds) == 0 {
|
||||
return messages, nil
|
||||
}
|
||||
fileidx := len(peer.DbIds) - 1
|
||||
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
||||
db, err := sql.Open("sqlite3", filepath.Join(cfg.StoragePath, identity.Uuid, peer.DbIds[fileidx]+GetConfig().DbSuffix)) // Open the created SQLite File
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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 dbm meowlib.DbMessage
|
||||
var id int64
|
||||
var m []byte
|
||||
err = rows.Scan(&id, &m)
|
||||
err := withDbRead(dbPath(cfg, identity, peer.DbIds[fileidx]), func(db *sql.DB) error {
|
||||
stm, err := db.Prepare("SELECT id, m FROM message WHERE id > ? ORDER BY id DESC")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
decdata, err := meowlib.SymDecrypt(password, m)
|
||||
defer stm.Close()
|
||||
rows, err := stm.Query(lastDbId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
err = proto.Unmarshal(decdata, &dbm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id int64
|
||||
var m []byte
|
||||
if err = rows.Scan(&id, &m); err != nil {
|
||||
return err
|
||||
}
|
||||
decdata, err := meowlib.SymDecrypt(password, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var dbm meowlib.DbMessage
|
||||
if err = proto.Unmarshal(decdata, &dbm); err != nil {
|
||||
return err
|
||||
}
|
||||
ium := DbMessageToInternalUserMessage(id, peer.DbIds[fileidx], &dbm)
|
||||
ium.Dbid = id
|
||||
ium.Dbfile = peer.DbIds[fileidx]
|
||||
messages = append(messages, ium)
|
||||
}
|
||||
|
||||
ium = DbMessageToInternalUserMessage(id, peer.DbIds[fileidx], &dbm)
|
||||
ium.Dbid = id
|
||||
ium.Dbfile = peer.DbIds[fileidx]
|
||||
messages = append(messages, ium)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
// TODO DB overlap
|
||||
return messages, nil
|
||||
return messages, err
|
||||
}
|
||||
|
||||
// Get old messages from a peer
|
||||
func loadMessagesHistory(peer *Peer, inAppMsgCount int, lastDbId int, wantMore int, password string) ([]InternalUserMessage, error) {
|
||||
var messages []InternalUserMessage
|
||||
// handle no db yet
|
||||
cfg := GetConfig()
|
||||
if len(peer.DbIds) == 0 {
|
||||
return messages, nil
|
||||
}
|
||||
fileidx := len(peer.DbIds) - 1
|
||||
// initialize count with last db message count
|
||||
countStack, err := getMessageCount(peer.DbIds[fileidx])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// while the db message count < what we already have in app, step to next db file
|
||||
for inAppMsgCount > countStack {
|
||||
fileidx--
|
||||
if fileidx < 0 {
|
||||
@@ -189,91 +197,80 @@ func loadMessagesHistory(peer *Peer, inAppMsgCount int, lastDbId int, wantMore i
|
||||
}
|
||||
countStack += newCount
|
||||
}
|
||||
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
||||
db, err := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, peer.DbIds[fileidx]+GetConfig().DbSuffix)) // Open the created SQLite File
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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 LIMIT ?")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer stm.Close()
|
||||
rows, err := stm.Query(lastDbId, wantMore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var ium *InternalUserMessage
|
||||
var dbm meowlib.DbMessage
|
||||
var id int64
|
||||
var m []byte
|
||||
err = rows.Scan(&id, &m)
|
||||
err = withDbRead(filepath.Join(cfg.StoragePath, cfg.GetIdentity().Uuid, peer.DbIds[fileidx]+cfg.DbSuffix), func(db *sql.DB) error {
|
||||
stm, err := db.Prepare("SELECT id, m FROM message WHERE id < ? ORDER BY id DESC LIMIT ?")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
decdata, err := meowlib.SymDecrypt(password, m)
|
||||
defer stm.Close()
|
||||
rows, err := stm.Query(lastDbId, wantMore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
err = proto.Unmarshal(decdata, &dbm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id int64
|
||||
var m []byte
|
||||
if err = rows.Scan(&id, &m); err != nil {
|
||||
return err
|
||||
}
|
||||
decdata, err := meowlib.SymDecrypt(password, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var dbm meowlib.DbMessage
|
||||
if err = proto.Unmarshal(decdata, &dbm); err != nil {
|
||||
return err
|
||||
}
|
||||
ium := DbMessageToInternalUserMessage(id, peer.DbIds[fileidx], &dbm)
|
||||
ium.Dbid = id
|
||||
ium.Dbfile = peer.DbIds[fileidx]
|
||||
messages = append(messages, *ium)
|
||||
}
|
||||
|
||||
ium = DbMessageToInternalUserMessage(id, peer.DbIds[fileidx], &dbm)
|
||||
ium.Dbid = id
|
||||
ium.Dbfile = peer.DbIds[fileidx]
|
||||
|
||||
messages = append(messages, *ium)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
// TODO DB overlap
|
||||
return messages, nil
|
||||
return messages, err
|
||||
}
|
||||
|
||||
func GetDbMessage(dbFile string, dbId int64, password string) (*meowlib.DbMessage, error) {
|
||||
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
||||
db, err := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite dbFile
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
stm, err := db.Prepare("SELECT id, m FROM message WHERE id=?")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer stm.Close()
|
||||
rows, err := stm.Query(dbId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
cfg := GetConfig()
|
||||
path := filepath.Join(cfg.StoragePath, cfg.GetIdentity().Uuid, dbFile+cfg.DbSuffix)
|
||||
var dbm meowlib.DbMessage
|
||||
found := false
|
||||
for rows.Next() {
|
||||
found = true
|
||||
var id int64
|
||||
var m []byte
|
||||
err = rows.Scan(&id, &m)
|
||||
err := withDbRead(path, func(db *sql.DB) error {
|
||||
stm, err := db.Prepare("SELECT id, m FROM message WHERE id=?")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
decdata, err := meowlib.SymDecrypt(password, m)
|
||||
defer stm.Close()
|
||||
rows, err := stm.Query(dbId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
err = proto.Unmarshal(decdata, &dbm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
found = true
|
||||
var id int64
|
||||
var m []byte
|
||||
if err = rows.Scan(&id, &m); err != nil {
|
||||
return err
|
||||
}
|
||||
decdata, err := meowlib.SymDecrypt(password, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = proto.Unmarshal(decdata, &dbm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !found {
|
||||
return nil, fmt.Errorf("message row %d not found in %s", dbId, dbFile)
|
||||
@@ -282,12 +279,8 @@ func GetDbMessage(dbFile string, dbId int64, password string) (*meowlib.DbMessag
|
||||
}
|
||||
|
||||
func UpdateDbMessage(dbm *meowlib.DbMessage, dbFile string, dbId int64, password string) error {
|
||||
db, err := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite dbFile
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
// Encrypt message
|
||||
cfg := GetConfig()
|
||||
path := filepath.Join(cfg.StoragePath, cfg.GetIdentity().Uuid, dbFile+cfg.DbSuffix)
|
||||
out, err := proto.Marshal(dbm)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -296,20 +289,16 @@ func UpdateDbMessage(dbm *meowlib.DbMessage, dbFile string, dbId int64, password
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Insert message
|
||||
updateMessageSQL := `UPDATE message SET m=? WHERE id=?`
|
||||
statement, err := db.Prepare(updateMessageSQL) // Prepare statement.
|
||||
if err != nil {
|
||||
return withDbWrite(path, func(db *sql.DB) error {
|
||||
stmt, err := db.Prepare(`UPDATE message SET m=? WHERE id=?`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = stmt.Exec(encData, dbId)
|
||||
return err
|
||||
}
|
||||
_, err = statement.Exec(encData, dbId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// Get old messages from a peer
|
||||
func GetMessagePreview(dbFile string, dbId int64, password string) ([]byte, error) {
|
||||
dbm, err := GetDbMessage(dbFile, dbId, password)
|
||||
if err != nil {
|
||||
@@ -318,24 +307,15 @@ func GetMessagePreview(dbFile string, dbId int64, password string) ([]byte, erro
|
||||
return FilePreview(dbm.FilePaths[0], password)
|
||||
}
|
||||
|
||||
// decrypt the a file and returns the raw content
|
||||
func FilePreview(filename string, password string) ([]byte, error) {
|
||||
// get the hidden file
|
||||
encData, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// decrypt the file
|
||||
data, err := meowlib.SymDecrypt(password, encData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
return meowlib.SymDecrypt(password, encData)
|
||||
}
|
||||
|
||||
// return the raw content from the files content (loads the first image, or build a more complex view)
|
||||
func InternalUserMessagePreview(msg *InternalUserMessage, password string) ([]byte, error) {
|
||||
// get the hidden file name
|
||||
if len(msg.FilePaths) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -343,21 +323,16 @@ func InternalUserMessagePreview(msg *InternalUserMessage, password string) ([]by
|
||||
}
|
||||
|
||||
func getMessageCount(dbid string) (int, error) {
|
||||
db, err := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbid+GetConfig().DbSuffix)) // Open the created SQLite File
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer db.Close()
|
||||
cfg := GetConfig()
|
||||
path := filepath.Join(cfg.StoragePath, cfg.GetIdentity().Uuid, dbid+cfg.DbSuffix)
|
||||
var count int
|
||||
query := "SELECT COUNT(*) FROM message"
|
||||
err = db.QueryRow(query).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
err := withDbRead(path, func(db *sql.DB) error {
|
||||
return db.QueryRow("SELECT COUNT(*) FROM message").Scan(&count)
|
||||
})
|
||||
return count, err
|
||||
}
|
||||
|
||||
// SetMessageServerDelivery updates the server delivery UUID and timestamp for an existing stored message.
|
||||
// SetMessageServerDelivery updates the server delivery UUID and timestamp for a stored message.
|
||||
func SetMessageServerDelivery(dbFile string, dbId int64, serverUid string, receiveTime uint64, password string) error {
|
||||
dbm, err := GetDbMessage(dbFile, dbId, password)
|
||||
if err != nil {
|
||||
@@ -375,37 +350,42 @@ func FindMessageByUuid(peer *Peer, messageUuid string, password string) (string,
|
||||
identity := cfg.GetIdentity()
|
||||
for i := len(peer.DbIds) - 1; i >= 0; i-- {
|
||||
dbid := peer.DbIds[i]
|
||||
db, err := sql.Open("sqlite3", filepath.Join(cfg.StoragePath, identity.Uuid, dbid+GetConfig().DbSuffix))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
rows, err := db.Query("SELECT id, m FROM message ORDER BY id DESC")
|
||||
if err != nil {
|
||||
db.Close()
|
||||
continue
|
||||
}
|
||||
for rows.Next() {
|
||||
var id int64
|
||||
var m []byte
|
||||
if err := rows.Scan(&id, &m); err != nil {
|
||||
continue
|
||||
}
|
||||
decdata, err := meowlib.SymDecrypt(password, m)
|
||||
path := filepath.Join(cfg.StoragePath, identity.Uuid, dbid+cfg.DbSuffix)
|
||||
var foundFile string
|
||||
var foundId int64
|
||||
var foundMsg meowlib.DbMessage
|
||||
err := withDbRead(path, func(db *sql.DB) error {
|
||||
rows, err := db.Query("SELECT id, m FROM message ORDER BY id DESC")
|
||||
if err != nil {
|
||||
continue
|
||||
return err
|
||||
}
|
||||
var dbm meowlib.DbMessage
|
||||
if err := proto.Unmarshal(decdata, &dbm); err != nil {
|
||||
continue
|
||||
}
|
||||
if dbm.Status != nil && dbm.Status.Uuid == messageUuid {
|
||||
rows.Close()
|
||||
db.Close()
|
||||
return dbid, id, &dbm, nil
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id int64
|
||||
var m []byte
|
||||
if err := rows.Scan(&id, &m); err != nil {
|
||||
continue
|
||||
}
|
||||
decdata, err := meowlib.SymDecrypt(password, m)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var dbm meowlib.DbMessage
|
||||
if err := proto.Unmarshal(decdata, &dbm); err != nil {
|
||||
continue
|
||||
}
|
||||
if dbm.Status != nil && dbm.Status.Uuid == messageUuid {
|
||||
foundFile = dbid
|
||||
foundId = id
|
||||
foundMsg = dbm
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err == nil && foundFile != "" {
|
||||
return foundFile, foundId, &foundMsg, nil
|
||||
}
|
||||
rows.Close()
|
||||
db.Close()
|
||||
}
|
||||
return "", 0, nil, fmt.Errorf("message with UUID %s not found", messageUuid)
|
||||
}
|
||||
@@ -430,19 +410,18 @@ func UpdateMessageAck(peer *Peer, messageUuid string, receivedAt uint64, process
|
||||
}
|
||||
|
||||
func createMessageTable(db *sql.DB) error {
|
||||
createMessageTableSQL := `CREATE TABLE message (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"m" BLOB);` // SQL Statement for Create Table
|
||||
statement, err := db.Prepare(createMessageTableSQL) // Prepare SQL Statement
|
||||
stmt, err := db.Prepare(`CREATE TABLE message (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"m" BLOB)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
statement.Exec() // Execute SQL Statements
|
||||
stmt.Exec()
|
||||
return nil
|
||||
}
|
||||
|
||||
func createServerTable(db *sql.DB) error {
|
||||
createServerTableSQL := `CREATE TABLE servers (
|
||||
stmt, err := db.Prepare(`CREATE TABLE servers (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"country" varchar(2),
|
||||
"public" bool,
|
||||
@@ -451,13 +430,12 @@ func createServerTable(db *sql.DB) error {
|
||||
"load" float,
|
||||
"url" varchar(2000)
|
||||
"name" varchar(255);
|
||||
"description" varchar(5000)
|
||||
"description" varchar(5000)
|
||||
"publickey" varchar(10000)
|
||||
)` // SQL Statement for Create Table
|
||||
statement, err := db.Prepare(createServerTableSQL) // Prepare SQL Statement
|
||||
)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
statement.Exec() // Execute SQL Statements
|
||||
stmt.Exec()
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user