149 lines
3.0 KiB
Go
149 lines
3.0 KiB
Go
package db
|
|
|
|
import (
|
|
"log"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
type MTP int32
|
|
|
|
const (
|
|
UNDEFINED MTP = iota
|
|
MQTT
|
|
STOMP
|
|
WEBSOCKETS
|
|
)
|
|
|
|
type Status uint8
|
|
|
|
const (
|
|
Offline Status = iota
|
|
Associating
|
|
Online
|
|
)
|
|
|
|
type Device struct {
|
|
SN string
|
|
Model string
|
|
Customer string
|
|
Vendor string
|
|
Version string
|
|
ProductClass string
|
|
Status Status
|
|
Mqtt Status
|
|
Stomp Status
|
|
Websockets Status
|
|
}
|
|
|
|
func (d *Database) CreateDevice(device Device) error {
|
|
var result bson.M
|
|
var deviceExistent Device
|
|
|
|
d.m.Lock()
|
|
defer d.m.Unlock()
|
|
|
|
/* ------------------ Do not overwrite status of other mtp ------------------ */
|
|
err := d.devices.FindOne(d.ctx, bson.D{{"sn", device.SN}}, nil).Decode(&deviceExistent)
|
|
if err == nil {
|
|
if deviceExistent.Mqtt == Online {
|
|
device.Mqtt = Online
|
|
}
|
|
if deviceExistent.Stomp == Online {
|
|
device.Stomp = Online
|
|
}
|
|
if deviceExistent.Websockets == Online {
|
|
device.Websockets = Online
|
|
}
|
|
} else {
|
|
if err != nil && err != mongo.ErrNoDocuments {
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
}
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
callback := func(sessCtx mongo.SessionContext) (interface{}, error) {
|
|
// Important: You must pass sessCtx as the Context parameter to the operations for them to be executed in the
|
|
// transaction.
|
|
opts := options.FindOneAndReplace().SetUpsert(true)
|
|
|
|
err = d.devices.FindOneAndReplace(d.ctx, bson.D{{"sn", device.SN}}, device, opts).Decode(&result)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
log.Printf("New device %s added to database", device.SN)
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
log.Printf("Device %s already existed, and got replaced for new info", device.SN)
|
|
return nil, nil
|
|
}
|
|
|
|
session, err := d.client.StartSession()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer session.EndSession(d.ctx)
|
|
|
|
_, err = session.WithTransaction(d.ctx, callback)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return err
|
|
}
|
|
func (d *Database) RetrieveDevices(filter bson.A) ([]Device, error) {
|
|
cursor, err := d.devices.Aggregate(d.ctx, filter)
|
|
|
|
var results []Device
|
|
|
|
for cursor.Next(d.ctx) {
|
|
var device Device
|
|
|
|
err := cursor.Decode(&device)
|
|
if err != nil {
|
|
log.Println("Error to decode device info fields")
|
|
continue
|
|
}
|
|
|
|
results = append(results, device)
|
|
}
|
|
|
|
return results, err
|
|
}
|
|
|
|
func (d *Database) RetrieveDevice(sn string) (Device, error) {
|
|
var result Device
|
|
//TODO: filter devices by user ownership
|
|
err := d.devices.FindOne(d.ctx, bson.D{{"sn", sn}}, nil).Decode(&result)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
return result, err
|
|
}
|
|
|
|
func (d *Database) RetrieveDevicesCount(filter bson.M) (int64, error) {
|
|
count, err := d.devices.CountDocuments(d.ctx, filter)
|
|
return count, err
|
|
}
|
|
|
|
func (d *Database) DeleteDevice() {
|
|
|
|
}
|
|
|
|
func (m MTP) String() string {
|
|
switch m {
|
|
case UNDEFINED:
|
|
return "unknown"
|
|
case MQTT:
|
|
return "mqtt"
|
|
case STOMP:
|
|
return "stomp"
|
|
case WEBSOCKETS:
|
|
return "websockets"
|
|
}
|
|
return "unknown"
|
|
}
|