diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c20cb3f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/main.go", + "env": {}, + "args": [] + } + ] +} \ No newline at end of file diff --git a/entities/device/device.go b/entities/device/device.go index e4cb389..4b6f668 100644 --- a/entities/device/device.go +++ b/entities/device/device.go @@ -1,7 +1,7 @@ package device type Device struct { - Id string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Keys map[string]string `json:"keys,omitempty"` + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Keys map[string]*Key `json:"keys,omitempty"` } diff --git a/entities/device/deviceController.go b/entities/device/deviceController.go index 9a04ad0..779c740 100644 --- a/entities/device/deviceController.go +++ b/entities/device/deviceController.go @@ -1,5 +1,5 @@ package device -func New() device *Device { - -} \ No newline at end of file +func New() (device *Device) { + return +} diff --git a/entities/device/key.go b/entities/device/key.go new file mode 100644 index 0000000..78153e0 --- /dev/null +++ b/entities/device/key.go @@ -0,0 +1,7 @@ +package device + +type Key struct { + Id string `json:"id,omitempty"` + Type string `json:"type,omitempty"` + Key string `json:"key,omitempty"` +} diff --git a/entities/event/edu.go b/entities/event/edu.go index 6ac9985..1ffed69 100644 --- a/entities/event/edu.go +++ b/entities/event/edu.go @@ -1,5 +1,7 @@ package event +// TODO: Check if it can be deleted + type EDU struct { Type string `json:"type,omitempty"` Content string `json:"content,omitempty"` diff --git a/entities/event/event.go b/entities/event/event.go index e139000..d6047b5 100644 --- a/entities/event/event.go +++ b/entities/event/event.go @@ -5,6 +5,6 @@ type Event struct { RoomId string `json:"roomId,omitempty"` EventType string `json:"eventType,omitempty"` Content string `json:"content,omitempty"` - Parent string `json:"parent,omitempty"` + ParentId string `json:"parent,omitempty"` Depth int `json:"depth,omitempty"` } diff --git a/entities/event/eventController.go b/entities/event/eventController.go index 8a315f1..9d03846 100644 --- a/entities/event/eventController.go +++ b/entities/event/eventController.go @@ -1,5 +1,5 @@ package event -func New() event *Event { - -} \ No newline at end of file +func New() (event *Event) { + return +} diff --git a/entities/room/room.go b/entities/room/room.go index cc65e98..712810c 100644 --- a/entities/room/room.go +++ b/entities/room/room.go @@ -5,9 +5,9 @@ import ( ) type Room struct { - Id string `json:"id,omitempty"` - Messages map[string]event.Event `json:"messages,omitempty"` - State map[string]event.Event `json:"state,omitempty"` - Members []string `json:"members,omitempty"` - Version string `json:"version,omitempty"` + Id string `json:"id,omitempty"` + Messages map[string]*event.Event `json:"messages,omitempty"` + //State map[string]event.Event `json:"state,omitempty"` + Members []string `json:"members,omitempty"` + Version string `json:"version,omitempty"` } diff --git a/entities/room/roomController.go b/entities/room/roomController.go index 75b6679..859931a 100644 --- a/entities/room/roomController.go +++ b/entities/room/roomController.go @@ -1,5 +1,5 @@ package room -func New() room *Room { - -} \ No newline at end of file +func New() (room *Room) { + return +} diff --git a/entities/transaction/transaction.go b/entities/transaction/transaction.go index 54a054e..3c0cb46 100644 --- a/entities/transaction/transaction.go +++ b/entities/transaction/transaction.go @@ -5,7 +5,9 @@ import ( ) type Transaction struct { - Id string `json:"id,omitempty"` - PDUS map[string]event.Event `json:"pdus,omitempty"` - EDUS []event.EDU `json:"edus,omitempty"` + Id string `json:"id,omitempty"` + Origin string `json:"origin,omitempty"` + Timestamp int `json:"timestamp,omitempty"` + PDUS map[string]*event.Event `json:"pdus,omitempty"` + //EDUS []event.EDU `json:"edus,omitempty"` } diff --git a/entities/transaction/transactionController.go b/entities/transaction/transactionController.go index 923edfb..fd8610a 100644 --- a/entities/transaction/transactionController.go +++ b/entities/transaction/transactionController.go @@ -1,5 +1,5 @@ package transaction -func New() transaction *Transaction { - -} \ No newline at end of file +func New() (transaction *Transaction) { + return +} diff --git a/entities/user/user.go b/entities/user/user.go index dc989aa..c28a9c0 100644 --- a/entities/user/user.go +++ b/entities/user/user.go @@ -5,8 +5,8 @@ import ( ) type User struct { - Id string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Password string `json:"password,omitempty"` - Devices map[string]device.Device `json:"devices,omitempty"` + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Password string `json:"password,omitempty"` + Devices map[string]*device.Device `json:"devices,omitempty"` } diff --git a/entities/user/userController.go b/entities/user/userController.go index 4bf992c..a75d68f 100644 --- a/entities/user/userController.go +++ b/entities/user/userController.go @@ -1,5 +1,5 @@ package user -func New() user *User { - -} \ No newline at end of file +func New() (user *User) { + return +} diff --git a/main.go b/main.go index 41638c8..8c38643 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,11 @@ package main import ( "encoding/json" - "fmt" "log" "net/http" "os" - "strconv" - "nutfactory.org/Matrix/utils" + "nutfactory.org/Matrix/utils/database" "nutfactory.org/Matrix/utils/router" ) @@ -75,18 +73,9 @@ func main() { // TODO: Remove later os.Remove("sqlite.db") - db := utils.InitDB("sqlite.db") + db, _ := database.InitDB("sqlite.db") defer db.Close() - rows, _ := db.Query("SELECT id, firstname, lastname FROM people") - var id int - var firstname string - var lastname string - for rows.Next() { - rows.Scan(&id, &firstname, &lastname) - fmt.Println(strconv.Itoa(id) + ": " + firstname + " " + lastname) - } - router := router.NewRouter(routes) //router.PathPrefix("/").Handler(http.FileServer(http.Dir(htmlPath))) diff --git a/sqlite.db b/sqlite.db new file mode 100644 index 0000000..59d87e3 Binary files /dev/null and b/sqlite.db differ diff --git a/utils/database/databaseConnector.go b/utils/database/databaseConnector.go index 87a00db..158cb6e 100644 --- a/utils/database/databaseConnector.go +++ b/utils/database/databaseConnector.go @@ -2,14 +2,15 @@ package database import ( "database/sql" + "fmt" "log" _ "github.com/mattn/go-sqlite3" ) -func InitDB(filepath string) *sql.DB { +func InitDB(filepath string) (db *sql.DB, err error) { log.Printf("Init DB") - db, err := sql.Open("sqlite3", filepath) + db, err = sql.Open("sqlite3", filepath) if err != nil { panic(err) } @@ -18,46 +19,17 @@ func InitDB(filepath string) *sql.DB { } handleError(initDeviceTable(db)) + handleError(initKeyTable(db)) handleError(initEventTable(db)) handleError(initRoomTable(db)) handleError(initTransactionTable(db)) handleError(initUserTable(db)) - return db + return } func handleError(err error) { if err != nil { - // TODO: Add Error Message - panic("Could not execute Database Query") + panic(fmt.Sprintf("Could not execute Database Query: %s", err)) } } - -/* -sqlStmt := fmt.Sprintf(`INSERT INTO data - (id, content) - VALUES - (?, ?)`) - -tx, err := db.Begin() -if err != nil { - log.Panic(err) -} - -stmt, err := tx.Prepare(sqlStmt) -if err != nil { - return err -} -defer stmt.Close() - -for i := 1; i < 10; i++ { - id := fmt.Sprintf("%d", i) - content := fmt.Sprintf("content #%d %s", i, shortuuid.New()) - log.Printf("Inserting %s: %s", id, content) - _, err := stmt.Exec(id, content) - if err != nil { - log.Panic(err) - } -} -tx.Commit() -*/ diff --git a/utils/database/deviceDatabaseConnector.go b/utils/database/deviceDatabaseConnector.go index 56efd34..047dbaf 100644 --- a/utils/database/deviceDatabaseConnector.go +++ b/utils/database/deviceDatabaseConnector.go @@ -1,29 +1,179 @@ -package device +package database import ( "database/sql" - + "fmt" + "log" + "nutfactory.org/Matrix/entities/device" ) -func initDeviceTable(db *sql.DB) err error { - // TODO: Change to correct Table-Structure - statement, err := db.Prepare("CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT)") +func initDeviceTable(db *sql.DB) (err error) { + log.Printf("Init Device Table") + statement, err := db.Prepare(`CREATE TABLE IF NOT EXISTS device ( + id TEXT PRIMARY KEY, + name TEXT, + userId TEXT + )`) + if err != nil { + return + } statement.Exec() + + /* + newDevice := &device.Device{Id: "test", Name: "TEST", Keys: nil} + err = CreateDevice(db, newDevice, "test") + if err != nil { + log.Printf("Error Create: %s", err) + return + } + newDevice.Name = "TEST2" + err = UpdateDevice(db, newDevice) + if err != nil { + log.Printf("Error Update: %s", err) + return + } + devices, err := ReadDevicesForUser(db, "test") + if err != nil { + log.Printf("Error Read User: %s", err) + return + } + log.Println(devices) + err = DeleteDevice(db, newDevice.Id) + if err != nil { + log.Printf("Error Delete: %s", err) + return + } + de, err := ReadDevice(db, "test") + if err != nil { + log.Printf("Error Read: %s", err) + return + } + if de != nil { + log.Printf("Device ID: %s Name: %s", de.Id, de.Name) + } else { + log.Printf("No Device found") + } + */ + + return } -func createDevice(db *sql.DB, device *Device) err error { +func CreateDevice(db *sql.DB, device *device.Device, userId string) (err error) { + sqlStmt := fmt.Sprintf(`INSERT INTO device + (id, name, userId) + VALUES + (?, ?, ?)`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(device.Id, device.Name, userId) + if err != nil { + return + } + tx.Commit() + return } -func readDevice(db *sql.DB, id string) (device *Device, err error) { +func ReadDevice(db *sql.DB, id string) (foundDevice *device.Device, err error) { + queryStmt := fmt.Sprintf(`SELECT id, name + FROM device + WHERE id = '%s'`, id) + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + if rows.Next() { + foundDevice = &device.Device{} + err = rows.Scan(&foundDevice.Id, &foundDevice.Name) + if err != nil { + return + } + foundDevice.Keys, err = ReadKeysForDevice(db, foundDevice.Id) + } + + return } -func updateDevice(db *sql.DB, device *Device) err error { +func ReadDevicesForUser(db *sql.DB, userId string) (devices map[string]*device.Device, err error) { + queryStmt := fmt.Sprintf(`SELECT id, name + FROM device + WHERE userId = '%s'`, userId) + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + devices = make(map[string]*device.Device) + + for rows.Next() { + foundDevice := &device.Device{} + err = rows.Scan(&foundDevice.Id, &foundDevice.Name) + if err != nil { + return + } + foundDevice.Keys, err = ReadKeysForDevice(db, foundDevice.Id) + devices[foundDevice.Id] = foundDevice + } + + return } -func deleteDevice(db *sql.DB, id string) err error { +func UpdateDevice(db *sql.DB, device *device.Device) (err error) { + sqlStmt := fmt.Sprintf(`UPDATE device SET + name = ? + WHERE id = ?`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(device.Name, device.Id) + if err != nil { + return + } + + tx.Commit() + return +} + +func DeleteDevice(db *sql.DB, id string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM device + WHERE id = '%s'`, id) + + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + tx.Commit() + return } diff --git a/utils/database/eventDatabaseConnector.go b/utils/database/eventDatabaseConnector.go index 9c94353..f635ea9 100644 --- a/utils/database/eventDatabaseConnector.go +++ b/utils/database/eventDatabaseConnector.go @@ -1,29 +1,278 @@ -package event +package database import ( "database/sql" + "fmt" + "log" "nutfactory.org/Matrix/entities/event" + "nutfactory.org/Matrix/entities/transaction" ) -func initEventTable(db *sql.DB) err error { - // TODO: Change to correct Table-Structure - statement, err := db.Prepare("CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT)") +func initEventTable(db *sql.DB) (err error) { + log.Printf("Init Event Table") + statement, err := db.Prepare(`CREATE TABLE IF NOT EXISTS event ( + id TEXT PRIMARY KEY, + roomId TEXT, + txnId TEXT, + eventType TEXT, + content TEXT, + parentId TEXT, + depth INTEGER + )`) + if err != nil { + return + } statement.Exec() + /* + newEvent := &event.Event{ + Id: "test", + RoomId: "test", + EventType: "test", + Content: "{TEST}", + ParentId: "test1", + Depth: 0, + } + err = CreateEvent(db, newEvent, "test") + if err != nil { + log.Printf("Error Create: %s", err) + return + } + eventsRoom, err := ReadEventsFromRoom(db, "test") + if err != nil { + log.Printf("Error Read User: %s", err) + return + } + log.Println(eventsRoom) + eventsTxn, err := ReadEventsFromTransaction(db, "test") + if err != nil { + log.Printf("Error Read User: %s", err) + return + } + log.Println(eventsTxn) + newEvent.Content = "{TEST123}" + err = UpdateEvent(db, newEvent) + if err != nil { + log.Printf("Error Update: %s", err) + return + } + err = DeleteEvent(db, newEvent.Id) + if err != nil { + log.Printf("Error Delete: %s", err) + return + } + readEvent, err := ReadEvent(db, "test") + if err != nil { + log.Printf("Error Read: %s", err) + return + } + if readEvent != nil { + log.Printf("Event ID: %s RoomId: %s EventType: %s Content: %s ParentId: %s Depth: %s", + readEvent.Id, readEvent.RoomId, readEvent.EventType, readEvent.Content, readEvent.ParentId, readEvent.Depth) + } else { + log.Printf("No Event found") + } + */ + return } -func createEvent(db *sql.DB, event *Event) err error { +func CreateEvent(db *sql.DB, event *event.Event, txnId string) (err error) { + sqlStmt := fmt.Sprintf(`INSERT INTO event + (id, roomId, txnId, eventType, content, parentId, depth) + VALUES + (?, ?, ?, ?, ?, ?, ?)`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(event.Id, event.RoomId, txnId, event.EventType, event.Content, event.ParentId, event.Depth) + if err != nil { + return + } + tx.Commit() + return } -func readEvent(db *sql.DB, id string) (event *Event, err error) { +func CreateEventsFromTransaction(db *sql.DB, transaction *transaction.Transaction) (err error) { + sqlStmt := fmt.Sprintf(`INSERT INTO event + (id, roomId, txnId, eventType, content, parentId, depth) + VALUES + (?, ?, ?, ?, ?, ?, ?)`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + for _, pdu := range transaction.PDUS { + _, err = stmt.Exec(pdu.Id, pdu.RoomId, transaction.Id, pdu.EventType, pdu.Content, pdu.ParentId, pdu.Depth) + if err != nil { + return + } + } + + tx.Commit() + return } -func updateEvent(db *sql.DB, event *Event) err error { +func ReadEvent(db *sql.DB, id string) (foundEvent *event.Event, err error) { + queryStmt := fmt.Sprintf(`SELECT id, roomId, eventType, content, parentId, depth + FROM event + WHERE id = '%s'`, id) + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + if rows.Next() { + foundEvent = &event.Event{} + err = rows.Scan(&foundEvent.Id, + &foundEvent.RoomId, + &foundEvent.EventType, + &foundEvent.Content, + &foundEvent.ParentId, + &foundEvent.Depth, + ) + if err != nil { + return + } + } + + return } -func deleteEvent(db *sql.DB, id string) err error { +func ReadEventsFromRoom(db *sql.DB, roomId string) (events map[string]*event.Event, err error) { + queryStmt := fmt.Sprintf(`SELECT id, roomId, eventType, content, parentId, depth + FROM event + WHERE roomId = '%s'`, roomId) + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + events = make(map[string]*event.Event) + + for rows.Next() { + foundEvent := &event.Event{} + err = rows.Scan(&foundEvent.Id, + &foundEvent.RoomId, + &foundEvent.EventType, + &foundEvent.Content, + &foundEvent.ParentId, + &foundEvent.Depth, + ) + if err != nil { + return + } + events[foundEvent.Id] = foundEvent + } + + return +} + +func ReadEventsFromTransaction(db *sql.DB, txnId string) (events map[string]*event.Event, err error) { + queryStmt := fmt.Sprintf(`SELECT id, roomId, eventType, content, parentId, depth + FROM event + WHERE txnId = '%s'`, txnId) + + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + events = make(map[string]*event.Event) + + for rows.Next() { + foundEvent := &event.Event{} + err = rows.Scan( + &foundEvent.Id, + &foundEvent.RoomId, + &foundEvent.EventType, + &foundEvent.Content, + &foundEvent.ParentId, + &foundEvent.Depth, + ) + if err != nil { + return + } + events[foundEvent.Id] = foundEvent + } + + return +} + +func UpdateEvent(db *sql.DB, event *event.Event) (err error) { + sqlStmt := fmt.Sprintf(`UPDATE event SET + roomId = ?, + eventType = ?, + content = ?, + parentId = ?, + depth = ? + WHERE id = ?`) + + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec( + event.RoomId, + event.EventType, + event.Content, + event.ParentId, + event.Depth, + event.Id, + ) + if err != nil { + return + } + + tx.Commit() + return +} + +func DeleteEvent(db *sql.DB, id string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM event + WHERE id = '%s'`, id) + + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + tx.Commit() + return } diff --git a/utils/database/keyDatabaseConnector.go b/utils/database/keyDatabaseConnector.go new file mode 100644 index 0000000..d7d2b7c --- /dev/null +++ b/utils/database/keyDatabaseConnector.go @@ -0,0 +1,177 @@ +package database + +import ( + "database/sql" + "fmt" + "log" + + "nutfactory.org/Matrix/entities/device" +) + +func initKeyTable(db *sql.DB) (err error) { + log.Printf("Init Key Table") + statement, err := db.Prepare(`CREATE TABLE IF NOT EXISTS key ( + id TEXT PRIMARY KEY, + type TEXT, + key TEXT, + deviceId TEXT + )`) + if err != nil { + return + } + statement.Exec() + /* + newKey := &device.Key{Id: "test", Type: "test", Key: "test"} + err = CreateKey(db, newKey, "test") + if err != nil { + log.Printf("Error Create: %s", err) + return + } + keys, err := ReadKeysForDevice(db, "test") + if err != nil { + log.Printf("Error Read Multiple: %s", err) + return + } + log.Println(keys) + newKey.Key = "TEST123" + err = UpdateKey(db, newKey) + if err != nil { + log.Printf("Error Update: %s", err) + return + } + err = DeleteKey(db, newKey.Id) + if err != nil { + log.Printf("Error Delete: %s", err) + return + } + readKey, err := ReadKey(db, "test") + if err != nil { + log.Printf("Error Read: %s", err) + return + } + if readKey != nil { + log.Printf("Key ID: %s Type: %s, Key: %s", readKey.Id, readKey.Type, readKey.Key) + } else { + log.Printf("No Key found") + } + */ + return +} + +func CreateKey(db *sql.DB, key *device.Key, deviceId string) (err error) { + sqlStmt := fmt.Sprintf(`INSERT INTO key + (id, type, key, deviceId) + VALUES + (?, ?, ?, ?)`) + + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(key.Id, key.Type, key.Key, deviceId) + if err != nil { + return + } + tx.Commit() + return +} + +func ReadKey(db *sql.DB, id string) (foundKey *device.Key, err error) { + queryStmt := fmt.Sprintf(`SELECT id, type, key + FROM key + WHERE id = '%s'`, id) + + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + if rows.Next() { + foundKey = &device.Key{} + err = rows.Scan(&foundKey.Id, &foundKey.Type, &foundKey.Key) + if err != nil { + return + } + } + + return +} + +func ReadKeysForDevice(db *sql.DB, deviceId string) (keys map[string]*device.Key, err error) { + queryStmt := fmt.Sprintf(`SELECT id, type, key + FROM key + WHERE deviceId = '%s'`, deviceId) + + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + keys = make(map[string]*device.Key) + + for rows.Next() { + foundKey := &device.Key{} + err = rows.Scan(&foundKey.Id, &foundKey.Type, &foundKey.Key) + if err != nil { + return + } + keys[foundKey.Id] = foundKey + } + + return +} + +func UpdateKey(db *sql.DB, key *device.Key) (err error) { + sqlStmt := fmt.Sprintf(`UPDATE key SET + type = ?, + key = ? + WHERE id = ?`) + + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(key.Type, key.Key, key.Id) + if err != nil { + return + } + + tx.Commit() + return +} + +func DeleteKey(db *sql.DB, id string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM key + WHERE id = '%s'`, id) + + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + tx.Commit() + return +} diff --git a/utils/database/roomDatabaseConnector.go b/utils/database/roomDatabaseConnector.go index 155210b..92890b7 100644 --- a/utils/database/roomDatabaseConnector.go +++ b/utils/database/roomDatabaseConnector.go @@ -1,29 +1,241 @@ -package room +package database import ( "database/sql" + "fmt" + "log" "nutfactory.org/Matrix/entities/room" ) -func initRoomTable(db *sql.DB) err error { - // TODO: Change to correct Table-Structure - statement, err := db.Prepare("CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT)") +func initRoomTable(db *sql.DB) (err error) { + log.Printf("Init Room Table") + statement, err := db.Prepare(`CREATE TABLE IF NOT EXISTS room ( + id TEXT PRIMARY KEY, + version TEXT + )`) + if err != nil { + return + } statement.Exec() + statement, err = db.Prepare(`CREATE TABLE IF NOT EXISTS roomMember ( + userId TEXT, + roomId TEXT, + PRIMARY KEY (userId, roomId) + )`) + if err != nil { + return + } + statement.Exec() + + //TODO: Test Queries + + return } -func createRoom(db *sql.DB, room *Room) err error { +func CreateRoom(db *sql.DB, room *room.Room, userId string) (err error) { + sqlStmt := fmt.Sprintf(`INSERT INTO room + (id, version) + VALUES + (?, ?)`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(room.Id, room.Version) + if err != nil { + return + } + tx.Commit() + err = CreateRoomMember(db, room.Id, userId) + return } -func readRoom(db *sql.DB, id string) (room *Room, err error) { +func CreateRoomMember(db *sql.DB, roomId string, userId string) (err error) { + sqlStmt := fmt.Sprintf(`INSERT INTO roomMember + (roomId, userId) + VALUES + (?, ?)`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(roomId, userId) + if err != nil { + return + } + tx.Commit() + return } -func updateRoom(db *sql.DB, room *Room) err error { +func ReadRoom(db *sql.DB, id string) (foundRoom *room.Room, err error) { + queryStmt := fmt.Sprintf(`SELECT id, version + FROM room + WHERE id = '%s'`, id) + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + if rows.Next() { + foundRoom = &room.Room{} + err = rows.Scan(&foundRoom.Id, &foundRoom.Version) + if err != nil { + return + } + foundRoom.Messages, err = ReadEventsFromRoom(db, foundRoom.Id) + if err != nil { + return + } + foundRoom.Members, err = ReadRoomMembers(db, foundRoom.Id) + if err != nil { + return + } + } + + return } -func deleteRoom(db *sql.DB, id string) err error { +func ReadRoomMembers(db *sql.DB, roomId string) (roomMembers []string, err error) { + queryStmt := fmt.Sprintf(`SELECT userId + FROM roomMember + WHERE roomId = '%s'`, roomId) + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + roomMembers = []string{} + + for rows.Next() { + var foundUser string + err = rows.Scan(&foundUser) + if err != nil { + return + } + roomMembers = append(roomMembers, foundUser) + } + + return +} + +func UpdateRoom(db *sql.DB, room *room.Room) (err error) { + sqlStmt := fmt.Sprintf(`UPDATE room SET + version = ? + WHERE id = ?`) + + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(room.Version, room.Id) + if err != nil { + return + } + + tx.Commit() + return +} + +func DeleteRoom(db *sql.DB, id string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM room + WHERE id = '%s'`, id) + + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + err = DeleteAllRoomMemberForRoom(db, id) + + tx.Commit() + return +} + +func DeleteRoomMember(db *sql.DB, roomId string, userId string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM roomMember + WHERE userId = '%s' AND roomId = '%s'`, userId, roomId) + + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + tx.Commit() + return +} + +func DeleteAllRoomMemberForUser(db *sql.DB, userId string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM roomMember + WHERE userId = '%s'`, userId) + + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + tx.Commit() + return +} + +func DeleteAllRoomMemberForRoom(db *sql.DB, roomId string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM roomMember + WHERE roomId = '%s'`, roomId) + + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + tx.Commit() + return } diff --git a/utils/database/transactionDatabaseConnector.go b/utils/database/transactionDatabaseConnector.go index 6917bcd..776972a 100644 --- a/utils/database/transactionDatabaseConnector.go +++ b/utils/database/transactionDatabaseConnector.go @@ -1,29 +1,119 @@ -package transaction +package database import ( "database/sql" + "fmt" + "log" "nutfactory.org/Matrix/entities/transaction" ) -func initTransactionTable(db *sql.DB) err error { - // TODO: Change to correct Table-Structure - statement, err := db.Prepare("CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT)") +func initTransactionTable(db *sql.DB) (err error) { + log.Printf("Init Transaction Table") + statement, err := db.Prepare(`CREATE TABLE IF NOT EXISTS txn ( + id TEXT PRIMARY KEY, + origin TEXT, + timestamp INTEGER + )`) + if err != nil { + return + } statement.Exec() + + //TODO: Test Queries + + return } -func createTransaction(db *sql.DB, transaction *Transaction) err error { +func createTransaction(db *sql.DB, transaction *transaction.Transaction) (err error) { + sqlStmt := fmt.Sprintf(`INSERT INTO txn + (id, origin, timestamp) + VALUES + (?, ?, ?)`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(transaction.Id, transaction.Origin, transaction.Timestamp) + if err != nil { + return + } + tx.Commit() + return } -func readTransaction(db *sql.DB, id string) (transaction *Transaction, err error) { +func readTransaction(db *sql.DB, id string) (foundTransaction *transaction.Transaction, err error) { + queryStmt := fmt.Sprintf(`SELECT id, origin, timestamp + FROM txn + WHERE id = '%s'`, id) + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + if rows.Next() { + foundTransaction = &transaction.Transaction{} + err = rows.Scan(&foundTransaction.Id, &foundTransaction.Origin, &foundTransaction.Timestamp) + if err != nil { + return + } + foundTransaction.PDUS, err = ReadEventsFromTransaction(db, foundTransaction.Id) + } + + return } -func updateTransaction(db *sql.DB, transaction *Transaction) err error { +func updateTransaction(db *sql.DB, transaction *transaction.Transaction) (err error) { + sqlStmt := fmt.Sprintf(`UPDATE txn SET + origin = ?, + timestamp = ? + WHERE id = ?`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(transaction.Origin, transaction.Timestamp, transaction.Id) + if err != nil { + return + } + + tx.Commit() + return } -func deleteTransaction(db *sql.DB, id string) err error { +func deleteTransaction(db *sql.DB, id string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM txn + WHERE id = '%s'`, id) + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + tx.Commit() + return } diff --git a/utils/database/userDatabaseConnector.go b/utils/database/userDatabaseConnector.go index f7d96d4..a9da638 100644 --- a/utils/database/userDatabaseConnector.go +++ b/utils/database/userDatabaseConnector.go @@ -1,29 +1,119 @@ -package user +package database import ( "database/sql" + "fmt" + "log" "nutfactory.org/Matrix/entities/user" ) -func initUserTable(db *sql.DB) err error { - // TODO: Change to correct Table-Structure - statement, err := db.Prepare("CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT)") +func initUserTable(db *sql.DB) (err error) { + log.Printf("Init User Table") + statement, err := db.Prepare(`CREATE TABLE IF NOT EXISTS user ( + id TEXT PRIMARY KEY, + name TEXT, + password TEXT + )`) + if err != nil { + return + } statement.Exec() + + //TODO: Test Queries + + return } -func createUser(db *sql.DB, user *User) err error { +func createUser(db *sql.DB, user *user.User) (err error) { + sqlStmt := fmt.Sprintf(`INSERT INTO user + (id, name, password) + VALUES + (?, ?, ?)`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(user.Id, user.Name, user.Password) + if err != nil { + return + } + tx.Commit() + return } -func readUser(db *sql.DB id string) (user *User, err error) { +func readUser(db *sql.DB, id string) (foundUser *user.User, err error) { + queryStmt := fmt.Sprintf(`SELECT id, name, password + FROM user + WHERE id = '%s'`, id) + rows, err := db.Query(queryStmt) + if err != nil { + return + } + + defer rows.Close() + + if rows.Next() { + foundUser = &user.User{} + err = rows.Scan(&foundUser.Id, &foundUser.Name, &foundUser.Password) + if err != nil { + return + } + foundUser.Devices, err = ReadDevicesForUser(db, foundUser.Id) + } + + return } -func updateUser(db *sql.DB, user *User) err error { +func updateUser(db *sql.DB, user *user.User) (err error) { + sqlStmt := fmt.Sprintf(`UPDATE user SET + name = ?, + password = ? + WHERE id = ?`) + tx, err := db.Begin() + if err != nil { + return + } + + stmt, err := tx.Prepare(sqlStmt) + if err != nil { + return + } + defer stmt.Close() + + _, err = stmt.Exec(user.Name, user.Password, user.Id) + if err != nil { + return + } + + tx.Commit() + return } -func deleteUser(db *sql.DB, id string) err error { +func deleteUser(db *sql.DB, id string) (err error) { + queryStmt := fmt.Sprintf(`DELETE FROM user + WHERE id = '%s'`, id) + tx, err := db.Begin() + if err != nil { + return + } + + _, err = db.Exec(queryStmt) + if err != nil { + return + } + + tx.Commit() + return }