|
|
|
@ -11,6 +11,8 @@ import (
|
|
|
|
|
"github.com/Masterminds/semver"
|
|
|
|
|
|
|
|
|
|
"github.com/go-flucky/flucky/pkg/types"
|
|
|
|
|
|
|
|
|
|
// PostgreSQL lib
|
|
|
|
|
_ "github.com/lib/pq"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@ -18,17 +20,19 @@ var (
|
|
|
|
|
postgresAssetPath = "pkg/storage/db/sql/psql"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Postgres provide functions to interact with a postgres database
|
|
|
|
|
type Postgres struct {
|
|
|
|
|
dbo *sql.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close the database connection
|
|
|
|
|
func (p *Postgres) Close() error {
|
|
|
|
|
return p.dbo.Close()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Schema create or upgrade database schema to the version of the flucky binary
|
|
|
|
|
// Schema create or updates the database schema to a given version. Normally the
|
|
|
|
|
// version is the same as the flucky binary version.
|
|
|
|
|
func (p *Postgres) Schema(ctx context.Context, version *semver.Version) error {
|
|
|
|
|
|
|
|
|
|
schemaFunc := func(ctx context.Context, fromVersion *semver.Version, toVersion *semver.Version) error {
|
|
|
|
|
|
|
|
|
|
assetPath := fmt.Sprintf("%v/schema", postgresAssetPath)
|
|
|
|
@ -94,9 +98,10 @@ func (p *Postgres) Schema(ctx context.Context, version *semver.Version) error {
|
|
|
|
|
}
|
|
|
|
|
return schemaFunc(ctx, fromVersion, version)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteDevices delete recursively all spicified devices, including sensors and
|
|
|
|
|
// all measured values
|
|
|
|
|
func (p *Postgres) DeleteDevices(ctx context.Context, devices []*types.Device) error {
|
|
|
|
|
asset := fmt.Sprintf("%v/deleteDevice.sql", postgresAssetPath)
|
|
|
|
|
queryBytes, err := Asset(asset)
|
|
|
|
@ -121,6 +126,8 @@ func (p *Postgres) DeleteDevices(ctx context.Context, devices []*types.Device) e
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteSensors delete recusively all spicified sensors, including all measured
|
|
|
|
|
// values
|
|
|
|
|
func (p *Postgres) DeleteSensors(ctx context.Context, sensors []*types.Sensor) error {
|
|
|
|
|
asset := fmt.Sprintf("%v/deleteSensor.sql", postgresAssetPath)
|
|
|
|
|
queryBytes, err := Asset(asset)
|
|
|
|
@ -145,6 +152,7 @@ func (p *Postgres) DeleteSensors(ctx context.Context, sensors []*types.Sensor) e
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteMeasuredValues delete all spicified measured values
|
|
|
|
|
func (p *Postgres) DeleteMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error {
|
|
|
|
|
|
|
|
|
|
deleteMeasuredValue := func(ctx context.Context, query string, measuredValues []*types.MeasuredValue) error {
|
|
|
|
@ -214,6 +222,7 @@ func (p *Postgres) DeleteMeasuredValues(ctx context.Context, measuredValues []*t
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// InsertDevices insert all specified devices into the database
|
|
|
|
|
func (p *Postgres) InsertDevices(ctx context.Context, devices []*types.Device) error {
|
|
|
|
|
asset := fmt.Sprintf("%v/insertDevice.sql", postgresAssetPath)
|
|
|
|
|
queryBytes, err := Asset(asset)
|
|
|
|
@ -238,6 +247,7 @@ func (p *Postgres) InsertDevices(ctx context.Context, devices []*types.Device) e
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// InsertInfo insert into the database additional informations, based on a key value syntax
|
|
|
|
|
func (p *Postgres) InsertInfo(ctx context.Context, key string, value string) error {
|
|
|
|
|
asset := fmt.Sprintf("%v/insertInfo.sql", postgresAssetPath)
|
|
|
|
|
queryBytes, err := Asset(asset)
|
|
|
|
@ -260,6 +270,7 @@ func (p *Postgres) InsertInfo(ctx context.Context, key string, value string) err
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// InsertMeasuredValues insert all specified measured values into the database
|
|
|
|
|
func (p *Postgres) InsertMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error {
|
|
|
|
|
|
|
|
|
|
sortedMeasuredValueTypes := make(map[types.MeasuredValueType][]*types.MeasuredValue)
|
|
|
|
@ -343,7 +354,7 @@ func (p *Postgres) insertPressure(ctx context.Context, measuredValues []*types.M
|
|
|
|
|
|
|
|
|
|
_, err := stmt.ExecContext(ctx, &measuredValue.ID, &measuredValue.Value, &measuredValue.FromDate, &measuredValue.TillDate, &measuredValue.SensorID, &measuredValue.CreationDate, &measuredValue.UpdateDate)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("%v: %v", errorStatementExecute, err)
|
|
|
|
|
return fmt.Errorf("%v: Measured value id %v: %v", errorStatementExecute, measuredValue.ID, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
@ -372,12 +383,13 @@ func (p *Postgres) insertTemperature(ctx context.Context, measuredValues []*type
|
|
|
|
|
|
|
|
|
|
_, err := stmt.ExecContext(ctx, &measuredValue.ID, &measuredValue.Value, &measuredValue.FromDate, &measuredValue.TillDate, &measuredValue.SensorID, &measuredValue.CreationDate, &measuredValue.UpdateDate)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("%v: %v", errorStatementExecute, err)
|
|
|
|
|
return fmt.Errorf("%v: Measured value id %v: %v", errorStatementExecute, measuredValue.ID, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// InsertSensors insert all specified sensors into the database
|
|
|
|
|
func (p *Postgres) InsertSensors(ctx context.Context, sensors []*types.Sensor) error {
|
|
|
|
|
|
|
|
|
|
asset := fmt.Sprintf("%v/insertSensor.sql", postgresAssetPath)
|
|
|
|
@ -403,6 +415,7 @@ func (p *Postgres) InsertSensors(ctx context.Context, sensors []*types.Sensor) e
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectDeviceByID returns a device by his ID
|
|
|
|
|
func (p *Postgres) SelectDeviceByID(ctx context.Context, id string) (*types.Device, error) {
|
|
|
|
|
asset := fmt.Sprintf("%v/selectDeviceByID.sql", postgresAssetPath)
|
|
|
|
|
queryBytes, err := Asset(asset)
|
|
|
|
@ -430,6 +443,7 @@ func (p *Postgres) SelectDeviceByID(ctx context.Context, id string) (*types.Devi
|
|
|
|
|
return device, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectInfo returns the value of a key stored in the database
|
|
|
|
|
func (p *Postgres) SelectInfo(ctx context.Context, key string) (string, error) {
|
|
|
|
|
asset := fmt.Sprintf("%v/selectInfo.sql", postgresAssetPath)
|
|
|
|
|
queryBytes, err := Asset(asset)
|
|
|
|
@ -457,6 +471,7 @@ func (p *Postgres) SelectInfo(ctx context.Context, key string) (string, error) {
|
|
|
|
|
return value, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectHumidities returns humidity values
|
|
|
|
|
func (p *Postgres) SelectHumidities(ctx context.Context) ([]*types.MeasuredValue, error) {
|
|
|
|
|
queryFile := fmt.Sprintf("%v/selectHumidities.sql", postgresAssetPath)
|
|
|
|
|
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeHumidity, queryFile, nil)
|
|
|
|
@ -466,6 +481,7 @@ func (p *Postgres) SelectHumidities(ctx context.Context) ([]*types.MeasuredValue
|
|
|
|
|
return measuredValues, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectHumidityByID returns a humidity value by his ID
|
|
|
|
|
func (p *Postgres) SelectHumidityByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
|
|
|
|
queryFile := fmt.Sprintf("%v/selectHumidityByID.sql", postgresAssetPath)
|
|
|
|
|
args := []interface{}{id}
|
|
|
|
@ -481,6 +497,30 @@ func (p *Postgres) SelectHumidityByID(ctx context.Context, id string) (*types.Me
|
|
|
|
|
return measuredValues[0], nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectMeasuredValues returns all measured values about all diffferent value
|
|
|
|
|
// types
|
|
|
|
|
func (p *Postgres) SelectMeasuredValues(ctx context.Context) ([]*types.MeasuredValue, error) {
|
|
|
|
|
measuredValues := make([]*types.MeasuredValue, 0)
|
|
|
|
|
|
|
|
|
|
// MeasuredValue query functions
|
|
|
|
|
queryFunctions := []func(ctx context.Context) ([]*types.MeasuredValue, error){
|
|
|
|
|
p.SelectHumidities,
|
|
|
|
|
p.SelectPressures,
|
|
|
|
|
p.SelectTemperatures,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Execute query functions
|
|
|
|
|
for _, queryFunction := range queryFunctions {
|
|
|
|
|
queriedMeasuredValues, err := queryFunction(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
measuredValues = append(measuredValues, queriedMeasuredValues...)
|
|
|
|
|
}
|
|
|
|
|
return measuredValues, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectMeasuredValuesByIDAndType returns a measured value by his ID and type
|
|
|
|
|
func (p *Postgres) SelectMeasuredValuesByIDAndType(ctx context.Context, id string, valueType types.MeasuredValueType) (*types.MeasuredValue, error) {
|
|
|
|
|
switch valueType {
|
|
|
|
|
case types.MeasuredValueTypeHumidity:
|
|
|
|
@ -494,6 +534,7 @@ func (p *Postgres) SelectMeasuredValuesByIDAndType(ctx context.Context, id strin
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectPressures returns pressure values
|
|
|
|
|
func (p *Postgres) SelectPressures(ctx context.Context) ([]*types.MeasuredValue, error) {
|
|
|
|
|
queryFile := fmt.Sprintf("%v/selectPressures.sql", postgresAssetPath)
|
|
|
|
|
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypePressure, queryFile, nil)
|
|
|
|
@ -503,6 +544,7 @@ func (p *Postgres) SelectPressures(ctx context.Context) ([]*types.MeasuredValue,
|
|
|
|
|
return measuredValues, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectPressureByID returns a pressure value by his ID
|
|
|
|
|
func (p *Postgres) SelectPressureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
|
|
|
|
queryFile := fmt.Sprintf("%v/selectPressureByID.sql", postgresAssetPath)
|
|
|
|
|
args := []interface{}{id}
|
|
|
|
@ -518,6 +560,7 @@ func (p *Postgres) SelectPressureByID(ctx context.Context, id string) (*types.Me
|
|
|
|
|
return measuredValues[0], nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectSensorByID returns a sensor by his ID
|
|
|
|
|
func (p *Postgres) SelectSensorByID(ctx context.Context, id string) (*types.Sensor, error) {
|
|
|
|
|
asset := fmt.Sprintf("%v/selectSensorByID.sql", postgresAssetPath)
|
|
|
|
|
queryBytes, err := Asset(asset)
|
|
|
|
@ -545,6 +588,7 @@ func (p *Postgres) SelectSensorByID(ctx context.Context, id string) (*types.Sens
|
|
|
|
|
return sensor, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectTemperatures returns temperature values
|
|
|
|
|
func (p *Postgres) SelectTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) {
|
|
|
|
|
queryFile := fmt.Sprintf("%v/selectTemperatures.sql", postgresAssetPath)
|
|
|
|
|
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeTemperature, queryFile, nil)
|
|
|
|
@ -554,6 +598,7 @@ func (p *Postgres) SelectTemperatures(ctx context.Context) ([]*types.MeasuredVal
|
|
|
|
|
return measuredValues, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SelectTemperatureByID returns a temperature value by his ID
|
|
|
|
|
func (p *Postgres) SelectTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
|
|
|
|
queryFile := fmt.Sprintf("%v/selectTemperatureByID.sql", postgresAssetPath)
|
|
|
|
|
args := []interface{}{id}
|
|
|
|
@ -597,10 +642,12 @@ func (p *Postgres) selectMeasuredValues(ctx context.Context, measuredValueType t
|
|
|
|
|
return measuredValues, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateDevices updates all specified devices into the database
|
|
|
|
|
func (p *Postgres) UpdateDevices(ctx context.Context, devices []*types.Device) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateInfo updates the value which is stored to a key in the database
|
|
|
|
|
func (p *Postgres) UpdateInfo(ctx context.Context, key string, value string) error {
|
|
|
|
|
asset := fmt.Sprintf("%v/updateInfo.sql", postgresAssetPath)
|
|
|
|
|
queryBytes, err := Asset(asset)
|
|
|
|
@ -623,10 +670,12 @@ func (p *Postgres) UpdateInfo(ctx context.Context, key string, value string) err
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateMeasuredValues updates the measured values which are stored in the database
|
|
|
|
|
func (p *Postgres) UpdateMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateSensors updates the sensors which are stored in the database
|
|
|
|
|
func (p *Postgres) UpdateSensors(ctx context.Context, sensots []*types.Sensor) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|