[add] initial commit

This commit is contained in:
2022-09-30 14:59:51 -05:00
commit 3da5d6a560
15 changed files with 825 additions and 0 deletions

19
app/models/model.go Normal file
View File

@@ -0,0 +1,19 @@
package models
import (
"gelvin/app/application"
)
type Model struct {
app *application.Application
}
func NewModel(app *application.Application) *Model {
return &Model{
app: app,
}
}
func Migrate(app *application.Application) error {
return app.Db().AutoMigrate(&Sensor{}, &Measurement{})
}

124
app/models/sensor.go Normal file
View File

@@ -0,0 +1,124 @@
package models
import (
"database/sql/driver"
"errors"
"gorm.io/gorm"
"strconv"
"strings"
"time"
)
type SensorType uint
const (
Temperature SensorType = iota + 1 // to allow gorm: not null
Humidity
Pressure
Gas
CO2
)
func (s SensorType) IsValid() bool {
switch s {
case Temperature, Humidity, Pressure, Gas, CO2:
return true
default:
return false
}
}
type Position struct {
X int `json:"x"`
Y int `json:"y"`
NotNull bool `json:"-"` // to allow gorm: not null with x/y = 0
}
type Sensor struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"-"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
Name string `json:"name" gorm:"uniqueIndex;not null;default:null"`
SensorType SensorType `json:"sensor_type" gorm:"not null;default:null"`
Position Position `json:"position" gorm:"not null;default:null"`
}
type Measurement struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"time"` // TODO: change to datetime2
UpdatedAt time.Time `json:"-"` // TODO: remove
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` // TODO: remove
SensorID uint `json:"sensor_id" gorm:"<-:create;not null;default:null"`
Sensor Sensor `json:"-"`
Value float64 `json:"value" gorm:"<-:create;default:null"` // TODO on migrate set column NOT NULL
}
func (s Sensor) IsValid() bool {
return s.SensorType.IsValid()
}
func (p Position) Value() (driver.Value, error) {
return strconv.FormatInt(int64(p.X), 10) + "." + strconv.FormatInt(int64(p.Y), 10), nil
}
func (p *Position) Scan(value interface{}) error {
p.X = 0
p.Y = 0
p.NotNull = true
positionString, isString := value.(string)
if !isString {
return errors.New("invalid scan value")
}
positionArray := strings.Split(positionString, ".")
if len(positionArray) != 2 {
return errors.New("invalid string value")
}
var err error
var position int64
position, err = strconv.ParseInt(positionArray[0], 10, 32)
if err != nil {
return errors.New("invalid x value")
}
p.X = int(position)
position, err = strconv.ParseInt(positionArray[1], 10, 32)
if err != nil {
return errors.New("invalid y value")
}
p.Y = int(position)
return nil
}
// http -v POST localhost:8080/sensors name="sensor_$RANDOM" sensor_type:=1 position:='{"x":1, "y":2}'
// http -v POST localhost:8080/sensors name="sensor_$RANDOM" sensor_type:=2
func (m Model) AddSensor(sensor Sensor) (uint, error) {
sensor.ID = 0
sensor.Position.NotNull = true
if !sensor.SensorType.IsValid() {
return 0, errors.New("invalid sensor type")
}
result := m.app.Db().Create(&sensor)
return sensor.ID, result.Error
}
func (m Model) UpdateSensor(sensor Sensor, txSensor Sensor, tx *gorm.DB) (uint, error) {
sensor.ID = txSensor.ID
sensor.Position.NotNull = true
if !sensor.SensorType.IsValid() {
return 0, errors.New("invalid sensor type")
}
result := tx.Updates(&sensor)
return sensor.ID, result.Error
}
// http -v POST localhost:8080/measurements sensor_id:=3 value:=32
// http -v GET localhost:8080/measurements/3
func (m Model) AddMeasurement(measurement Measurement) (uint, error) {
measurement.ID = 0
err := m.app.Db().First(&Sensor{}, measurement.SensorID).Error
if err != nil {
return 0, err
}
result := m.app.Db().Create(&measurement)
return measurement.ID, result.Error
}