[PD1] Added SQLlite queries and minor protocol changes
This commit is contained in:
parent
1e12bcde6c
commit
23584e2901
6 changed files with 213 additions and 46 deletions
|
@ -1 +1,156 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"PD1/internal/protocol"
|
||||
"database/sql"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
type DataStore struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func OpenDB() DataStore {
|
||||
db, err := sql.Open("sqlite3", "server.db")
|
||||
if err != nil {
|
||||
log.Fatalln("Error opening db file")
|
||||
}
|
||||
return DataStore{db: db}
|
||||
}
|
||||
|
||||
func (ds DataStore) CreateTables() error {
|
||||
// Create users table
|
||||
_, err := ds.db.Exec(`CREATE TABLE IF NOT EXISTS users (
|
||||
UID TEXT PRIMARY KEY,
|
||||
userCert BLOB
|
||||
)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create messages table
|
||||
_, err = ds.db.Exec(`CREATE TABLE IF NOT EXISTS messages (
|
||||
fromUID TEXT,
|
||||
toUID TEXT,
|
||||
timestamp TIMESTAMP,
|
||||
content BLOB,
|
||||
PRIMARY KEY (toUID, fromUID, timestamp),
|
||||
FOREIGN KEY(fromUID) REFERENCES users(UID),
|
||||
FOREIGN KEY(toUID) REFERENCES users(UID)
|
||||
)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds DataStore) GetMessage(toUID string, position int) protocol.ServerMessagePacket {
|
||||
|
||||
var serverMessage protocol.ServerMessagePacket
|
||||
query := `
|
||||
SELECT fromUID, toUID, content, timestamp
|
||||
FROM messages
|
||||
WHERE toUID = ?
|
||||
AND status = 0
|
||||
ORDER BY timestamp
|
||||
LIMIT 1 OFFSET ?
|
||||
`
|
||||
// Execute the query
|
||||
row := ds.db.QueryRow(query, toUID, position)
|
||||
err := row.Scan(&serverMessage.FromUID, &serverMessage.ToUID, &serverMessage.Content, &serverMessage.Timestamp)
|
||||
if err != nil {
|
||||
log.Panicln("Could not map DB query to ServerMessage")
|
||||
}
|
||||
return serverMessage
|
||||
|
||||
}
|
||||
|
||||
func (ds DataStore) MarkMessageInQueueAsRead(toUID string, position int) error {
|
||||
query := `
|
||||
UPDATE messages
|
||||
SET status = 1
|
||||
WHERE toUID = ? AND status = 0
|
||||
ORDER BY timestamp
|
||||
LIMIT 1 OFFSET ?
|
||||
`
|
||||
|
||||
// Execute the SQL statement
|
||||
_, err := ds.db.Exec(query, toUID, position)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds DataStore) GetAllMessages(toUID string) []protocol.Packet {
|
||||
var messagePackets []protocol.Packet
|
||||
|
||||
// Query to retrieve all messages from the user's queue
|
||||
query := `
|
||||
SELECT fromUID, toUID, content, timestamp
|
||||
FROM messages
|
||||
WHERE toUID = ?
|
||||
AND status = 0
|
||||
ORDER BY timestamp
|
||||
`
|
||||
|
||||
// Execute the query
|
||||
rows, err := ds.db.Query(query, toUID)
|
||||
if err != nil {
|
||||
log.Panicln("Failed to execute query:", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
// Iterate through the result set and scan each row into a ServerMessage struct
|
||||
for rows.Next() {
|
||||
var fromUID string
|
||||
var toUID string
|
||||
var content []byte
|
||||
var timestamp time.Time
|
||||
if err := rows.Scan(&fromUID, &toUID, &content, ×tamp); err != nil {
|
||||
log.Panicln("Failed to scan row:", err)
|
||||
}
|
||||
message := protocol.NewMessagePacket(fromUID, toUID, content, timestamp)
|
||||
messagePackets = append(messagePackets, message)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
log.Panicln("Error when getting user's messages")
|
||||
}
|
||||
|
||||
return messagePackets
|
||||
}
|
||||
|
||||
func (ds DataStore) AddMessageToQueue(uid string, message protocol.SubmitMessagePacket) {
|
||||
query := `
|
||||
INSERT INTO messages (fromUID, toUID, content, timestamp, status)
|
||||
VALUES (?, ?, ?, ?, 0)
|
||||
`
|
||||
|
||||
// Execute the SQL statement
|
||||
currentTime := time.Now()
|
||||
_, err := ds.db.Exec(query, uid, message.ToUID, message.Content, currentTime)
|
||||
if err != nil {
|
||||
log.Panicln("Error adding message to database")
|
||||
}
|
||||
}
|
||||
|
||||
func (ds DataStore) GetUserCertificate(uid string) protocol.Packet {
|
||||
query := `
|
||||
SELECT userCert
|
||||
FROM users
|
||||
WHERE UID = ?
|
||||
`
|
||||
|
||||
// Execute the SQL query
|
||||
var userCert []byte
|
||||
err := ds.db.QueryRow(query, uid).Scan(&userCert)
|
||||
if err != nil {
|
||||
log.Panicln("Error getting user certificate from the database")
|
||||
}
|
||||
return protocol.NewSendUserCertPacket(uid, userCert)
|
||||
}
|
||||
|
|
|
@ -6,19 +6,23 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
func clientHandler(connection networking.Connection[protocol.Packet]) {
|
||||
defer connection.Conn.Close()
|
||||
func clientHandler(connection networking.Connection[protocol.Packet], dataStore DataStore) {
|
||||
defer connection.Conn.Close()
|
||||
|
||||
// FIX: GET THE UID FROM THE USER CERTIFICATE FROM THE TLS SESSION
|
||||
uid := "0"
|
||||
|
||||
for {
|
||||
pac := connection.Receive()
|
||||
pac := connection.Receive()
|
||||
switch pac.Flag {
|
||||
case protocol.ReqPK:
|
||||
fmt.Println("ReqPK")
|
||||
case protocol.ReqAllMsg:
|
||||
case protocol.ReqUserCertPkt:
|
||||
userCertPacket := dataStore.GetUserCertificate(uid)
|
||||
connection.Send(userCertPacket)
|
||||
case protocol.ReqAllMsgPkt:
|
||||
fmt.Println("ReqAllMsg")
|
||||
case protocol.ReqMsg:
|
||||
case protocol.ReqMsgPkt:
|
||||
fmt.Println("ReqMsg")
|
||||
case protocol.SubmitMsg:
|
||||
case protocol.SubmitMsgPkt:
|
||||
fmt.Println("SubmitMsg")
|
||||
}
|
||||
}
|
||||
|
@ -26,13 +30,18 @@ func clientHandler(connection networking.Connection[protocol.Packet]) {
|
|||
}
|
||||
|
||||
func Run(port int) {
|
||||
server := networking.NewServer[protocol.Packet](port)
|
||||
go server.ListenLoop()
|
||||
//Open connection to DB
|
||||
dataStore := OpenDB()
|
||||
defer dataStore.db.Close()
|
||||
|
||||
//Create server listener
|
||||
server := networking.NewServer[protocol.Packet](port)
|
||||
go server.ListenLoop()
|
||||
|
||||
for {
|
||||
//Receive Connection via channel
|
||||
conn := <-server.C
|
||||
//Launch client handler via clientHandler
|
||||
go clientHandler(conn)
|
||||
go clientHandler(conn, dataStore)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue