diff --git a/pkg/repository/db/db.go b/pkg/repository/db/db.go index c793750..0920e58 100644 --- a/pkg/repository/db/db.go +++ b/pkg/repository/db/db.go @@ -20,8 +20,11 @@ type Database interface { DeleteDevices(ctx context.Context, deviceIDs ...string) error DeleteSensors(ctx context.Context, sensorIDs ...string) error InsertDevices(ctx context.Context, devices ...*types.Device) error + InsertOrUpdateDevices(ctx context.Context, devices ...*types.Device) error InsertMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error + InsertOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error InsertSensors(ctx context.Context, sensors ...*types.Sensor) error + InsertOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error Scheme(ctx context.Context) error SelectDevice(ctx context.Context, deviceID string) (*types.Device, error) SelectDevices(ctx context.Context) ([]*types.Device, error) diff --git a/pkg/repository/db/postgres.go b/pkg/repository/db/postgres.go index 49424bd..97ee594 100644 --- a/pkg/repository/db/postgres.go +++ b/pkg/repository/db/postgres.go @@ -85,17 +85,26 @@ func (postgres *Postgres) DeleteSensors(ctx context.Context, sensorIDs ...string // InsertDevices into the database func (postgres *Postgres) InsertDevices(ctx context.Context, devices ...*types.Device) error { + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + + err = postgres.insertDevices(tx, devices...) + if err != nil { + return err + } + + return tx.Commit() +} + +func (postgres *Postgres) insertDevices(tx *sql.Tx, devices ...*types.Device) error { queryFile := "insertDevice.sql" query, present := postgres.queries[queryFile] if !present { return fmt.Errorf("Postgres-Backend: File %v not found", queryFile) } - tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - stmt, err := tx.Prepare(query) if err != nil { return fmt.Errorf("Failed to prepare statement: %v", err) @@ -121,7 +130,7 @@ func (postgres *Postgres) InsertDevices(ctx context.Context, devices ...*types.D } } - return tx.Commit() + return nil } // InsertMeasuredValues into the database @@ -201,6 +210,167 @@ func (postgres *Postgres) InsertMeasuredValues(ctx context.Context, measuredValu return tx.Commit() } +func (postgres *Postgres) InsertOrUpdateDevices(ctx context.Context, devices ...*types.Device) error { + queryFile := "insertOrUpdateDevice.sql" + query, present := postgres.queries[queryFile] + if !present { + return fmt.Errorf("Postgres-Backend: File %v not found", queryFile) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + + for _, device := range devices { + + if device.CreationDate.Equal(time.Time{}) { + device.CreationDate = time.Now() + } + + _, err = tx.Exec( + query, + &device.ID, + &device.Name, + &device.Location, + &device.CreationDate, + &device.UpdateDate, + ) + if err != nil { + tx.Rollback() + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return tx.Commit() +} + +// InsertOrUpdateMeasuredValues into the database +func (postgres *Postgres) InsertOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error { + splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0) + + for _, measuredValue := range measuredValues { + if _, ok := splittedMeasuredValues[measuredValue.ValueType]; !ok { + splittedMeasuredValues[measuredValue.ValueType] = make([]*types.MeasuredValue, 0) + } + splittedMeasuredValues[measuredValue.ValueType] = append(splittedMeasuredValues[measuredValue.ValueType], measuredValue) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + + // General insert function + insert := func(tx *sql.Tx, queryFile string, measuredValues []*types.MeasuredValue) error { + query, present := postgres.queries[queryFile] + if !present { + return fmt.Errorf("Postgres-Backend: File %v not found", queryFile) + } + + stmt, err := tx.Prepare(query) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, measuredValue := range measuredValues { + + if measuredValue.CreationDate.Equal(time.Time{}) { + measuredValue.CreationDate = time.Now() + } + + _, err := stmt.Exec( + &measuredValue.ID, + &measuredValue.Value, + &measuredValue.Date, + &measuredValue.SensorID, + &measuredValue.CreationDate, + &measuredValue.UpdateDate, + ) + + if err != nil { + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return nil + } + + for measuredValueType, measuredValues := range splittedMeasuredValues { + var queryFile string + + switch measuredValueType { + case types.Humidity: + queryFile = "insertOrUpdateHumidity.sql" + case types.Pressure: + queryFile = "insertOrUpdatePressure.sql" + case types.Temperature: + queryFile = "insertOrUpdateTemperature.sql" + default: + tx.Rollback() + return fmt.Errorf("Measured value type %v not supported", measuredValueType) + } + + err := insert(tx, queryFile, measuredValues) + if err != nil { + tx.Rollback() + return err + } + } + + return tx.Commit() +} + +// InsertOrUpdateSensors into the database +func (postgres *Postgres) InsertOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error { + queryFile := "insertOrUpdateSensor.sql" + query, present := postgres.queries[queryFile] + if !present { + return fmt.Errorf("Postgres-Backend: File %v not found", queryFile) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + + stmt, err := tx.Prepare(query) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, sensor := range sensors { + + if sensor.CreationDate.Equal(time.Time{}) { + sensor.CreationDate = time.Now() + } + + _, err = stmt.Exec( + &sensor.ID, + &sensor.Name, + &sensor.Location, + &sensor.WireID, + &sensor.I2CBus, + &sensor.I2CAddress, + &sensor.GPIONumber, + &sensor.Model, + &sensor.Enabled, + &sensor.TickDuration, + &sensor.DeviceID, + &sensor.CreationDate, + &sensor.UpdateDate, + ) + if err != nil { + tx.Rollback() + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return tx.Commit() +} + // InsertSensors into the database func (postgres *Postgres) InsertSensors(ctx context.Context, sensors ...*types.Sensor) error { queryFile := "insertSensor.sql" @@ -438,8 +608,8 @@ func (postgres *Postgres) selectMeasuredValue(tx *sql.Tx, query string, args ... err := rows.Scan( &measuredValue.ID, &measuredValue.Value, - &measuredValue.SensorID, &measuredValue.Date, + &measuredValue.SensorID, &measuredValue.CreationDate, &measuredValue.UpdateDate, ) diff --git a/pkg/repository/db/postgres/insertOrUpdateDevice.sql b/pkg/repository/db/postgres/insertOrUpdateDevice.sql new file mode 100644 index 0000000..ddeda57 --- /dev/null +++ b/pkg/repository/db/postgres/insertOrUpdateDevice.sql @@ -0,0 +1,14 @@ +INSERT INTO devices ( + device_id, + device_name, + device_location, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5) +ON CONFLICT (device_id) +DO + UPDATE SET + device_name = EXCLUDED.device_name, + device_location = EXCLUDED.device_location, + update_date = NOW(); \ No newline at end of file diff --git a/pkg/repository/db/postgres/insertOrUpdateHumidity.sql b/pkg/repository/db/postgres/insertOrUpdateHumidity.sql new file mode 100644 index 0000000..4cfd294 --- /dev/null +++ b/pkg/repository/db/postgres/insertOrUpdateHumidity.sql @@ -0,0 +1,16 @@ +INSERT INTO humidities ( + id, + value, + date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6) +ON CONFLICT (id) +DO + UPDATE SET + value = EXCLUDED.value, + date = EXCLUDED.date, + sensor_id = EXCLUDED.sensor_id, + update_date = NOW(); \ No newline at end of file diff --git a/pkg/repository/db/postgres/insertOrUpdatePressure.sql b/pkg/repository/db/postgres/insertOrUpdatePressure.sql new file mode 100644 index 0000000..c22a280 --- /dev/null +++ b/pkg/repository/db/postgres/insertOrUpdatePressure.sql @@ -0,0 +1,16 @@ +INSERT INTO pressures ( + id, + value, + date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6) +ON CONFLICT (id) +DO + UPDATE SET + value = EXCLUDED.value, + date = EXCLUDED.date, + sensor_id = EXCLUDED.sensor_id, + update_date = NOW(); \ No newline at end of file diff --git a/pkg/repository/db/postgres/insertOrUpdateSensor.sql b/pkg/repository/db/postgres/insertOrUpdateSensor.sql new file mode 100644 index 0000000..0b743bc --- /dev/null +++ b/pkg/repository/db/postgres/insertOrUpdateSensor.sql @@ -0,0 +1,31 @@ +INSERT INTO sensors ( + sensor_id, + sensor_name, + sensor_location, + wire_id, + i2c_bus, + i2c_address, + gpio_number, + sensor_model, + sensor_enabled, + tick_duration, + device_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) +ON CONFLICT (sensor_id) +DO + UPDATE SET + sensor_name = EXCLUDED.sensor_name, + sensor_location = EXCLUDED.sensor_location, + wire_id = EXCLUDED.wire_id, + i2c_bus = EXCLUDED.i2c_bus, + i2c_address = EXCLUDED.i2c_address, + gpio_number = EXCLUDED.gpio_number, + sensor_model = EXCLUDED.sensor_model, + sensor_enabled = EXCLUDED.sensor_enabled, + tick_duration = EXCLUDED.tick_duration, + device_id = EXCLUDED.device_id, + creation_date = EXCLUDED.creation_date, + update_date = NOW(); diff --git a/pkg/repository/db/postgres/insertOrUpdateTemperature.sql b/pkg/repository/db/postgres/insertOrUpdateTemperature.sql new file mode 100644 index 0000000..42b7f17 --- /dev/null +++ b/pkg/repository/db/postgres/insertOrUpdateTemperature.sql @@ -0,0 +1,16 @@ +INSERT INTO temperatures ( + id, + value, + date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6) +ON CONFLICT (id) +DO + UPDATE SET + value = EXCLUDED.value, + date = EXCLUDED.date, + sensor_id = EXCLUDED.sensor_id, + update_date = NOW(); \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectHumidity.sql b/pkg/repository/db/postgres/selectHumidity.sql index 78ebc28..7e8fa06 100644 --- a/pkg/repository/db/postgres/selectHumidity.sql +++ b/pkg/repository/db/postgres/selectHumidity.sql @@ -8,4 +8,4 @@ SELECT FROM humidities WHERE - humidity_id = $1 \ No newline at end of file + id = $1 \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectPressure.sql b/pkg/repository/db/postgres/selectPressure.sql index 08f8a71..fc295c2 100644 --- a/pkg/repository/db/postgres/selectPressure.sql +++ b/pkg/repository/db/postgres/selectPressure.sql @@ -8,4 +8,4 @@ SELECT FROM pressures WHERE - pressure_id = $1 \ No newline at end of file + id = $1 \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectTemperature.sql b/pkg/repository/db/postgres/selectTemperature.sql index 51ab33a..5696656 100644 --- a/pkg/repository/db/postgres/selectTemperature.sql +++ b/pkg/repository/db/postgres/selectTemperature.sql @@ -8,4 +8,4 @@ SELECT FROM temperatures WHERE - temperature_id = $1 \ No newline at end of file + id = $1 \ No newline at end of file diff --git a/pkg/repository/db/sqlite.go b/pkg/repository/db/sqlite.go index d2bf8d5..6a12239 100644 --- a/pkg/repository/db/sqlite.go +++ b/pkg/repository/db/sqlite.go @@ -82,6 +82,42 @@ func (sqlite *SQLite) DeleteSensors(ctx context.Context, sensorIDs ...string) er return tx.Commit() } +func (sqlite *SQLite) ExistDevice(ctx context.Context, deviceID string) (bool, error) { + queryFile := "existDevice.sql" + query, present := sqlite.queries[queryFile] + if !present { + return false, fmt.Errorf("SQLite-Backend: File %v not found", queryFile) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return false, fmt.Errorf("Failed to begin new transaction: %v", err) + } + + stmt, err := tx.Prepare(query) + if err != nil { + return false, fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + rows, err := stmt.Query() + if err != nil { + return false, fmt.Errorf("Failed to query statement: %v", err) + } + defer rows.Close() + + var t bool + for rows.Next() { + rows.Scan(&t) + } + + return t, nil +} + +func (sqlite *SQLite) ExistDevices(ctx context.Context, deviceIDs ...string) (map[string]bool, error) { + return nil, nil +} + // InsertDevices into the database func (sqlite *SQLite) InsertDevices(ctx context.Context, devices ...*types.Device) error { queryFile := "insertDevice.sql" @@ -184,6 +220,152 @@ func (sqlite *SQLite) InsertMeasuredValues(ctx context.Context, measuredValues . return tx.Commit() } +// InsertOrUpdateMeasuredValues into the database +func (sqlite *SQLite) InsertOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error { + splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0) + + for _, measuredValue := range measuredValues { + if _, ok := splittedMeasuredValues[measuredValue.ValueType]; !ok { + splittedMeasuredValues[measuredValue.ValueType] = make([]*types.MeasuredValue, 0) + } + splittedMeasuredValues[measuredValue.ValueType] = append(splittedMeasuredValues[measuredValue.ValueType], measuredValue) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + + // General insert function + insert := func(tx *sql.Tx, queryFile string, measuredValues []*types.MeasuredValue) error { + query, present := sqlite.queries[queryFile] + if !present { + return fmt.Errorf("SQLite-Backend: File %v not found", queryFile) + } + + stmt, err := tx.Prepare(query) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, measuredValue := range measuredValues { + _, err := stmt.Exec( + &measuredValue.ID, + &measuredValue.Value, + &measuredValue.Date, + &measuredValue.SensorID, + &measuredValue.CreationDate, + &measuredValue.UpdateDate, + ) + + if err != nil { + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return nil + } + + for measuredValueType, measuredValues := range splittedMeasuredValues { + var queryFile string + + switch measuredValueType { + case types.Humidity: + queryFile = "insertOrUpdateHumidity.sql" + case types.Pressure: + queryFile = "insertOrUpdatePressure.sql" + case types.Temperature: + queryFile = "insertOrUpdateTemperature.sql" + default: + tx.Rollback() + return fmt.Errorf("Measured value type %v not supported", measuredValueType) + } + + err := insert(tx, queryFile, measuredValues) + if err != nil { + tx.Rollback() + return err + } + } + + return tx.Commit() +} + +// InsertOrUpdateDevices into the database +func (sqlite *SQLite) InsertOrUpdateDevices(ctx context.Context, devices ...*types.Device) error { + queryFile := "insertOrUpdateDevice.sql" + query, present := sqlite.queries[queryFile] + if !present { + return fmt.Errorf("SQLite-Backend: File %v not found", queryFile) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + + stmt, err := tx.Prepare(query) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, device := range devices { + _, err = stmt.Exec(&device.ID, &device.Name, &device.Location, &device.CreationDate, &device.UpdateDate) + if err != nil { + tx.Rollback() + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return tx.Commit() +} + +// InsertOrUpdateSensors into the database +func (sqlite *SQLite) InsertOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error { + queryFile := "insertOrUpdateSensor.sql" + query, present := sqlite.queries[queryFile] + if !present { + return fmt.Errorf("SQLite-Backend: File %v not found", queryFile) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + + stmt, err := tx.Prepare(query) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, sensor := range sensors { + _, err = stmt.Exec( + &sensor.ID, + &sensor.Name, + &sensor.Location, + &sensor.WireID, + &sensor.I2CBus, + &sensor.I2CAddress, + &sensor.GPIONumber, + &sensor.Model, + &sensor.Enabled, + &sensor.TickDuration, + &sensor.DeviceID, + &sensor.CreationDate, + &sensor.UpdateDate, + ) + if err != nil { + tx.Rollback() + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return tx.Commit() +} + // InsertSensors into the database func (sqlite *SQLite) InsertSensors(ctx context.Context, sensors ...*types.Sensor) error { queryFile := "insertSensor.sql" diff --git a/pkg/repository/db/sqlite3/insertOrUpdateDevice.sql b/pkg/repository/db/sqlite3/insertOrUpdateDevice.sql new file mode 100644 index 0000000..1886add --- /dev/null +++ b/pkg/repository/db/sqlite3/insertOrUpdateDevice.sql @@ -0,0 +1,14 @@ +INSERT INTO devices ( + device_id, + device_name, + device_location, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5) +ON CONFLICT (device_id) +DO + UPDATE SET + device_name = EXCLUDED.device_name, + device_location = EXCLUDED.device_location, + update_date = date('now'); \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/insertOrUpdateHumidity.sql b/pkg/repository/db/sqlite3/insertOrUpdateHumidity.sql new file mode 100644 index 0000000..91a6aad --- /dev/null +++ b/pkg/repository/db/sqlite3/insertOrUpdateHumidity.sql @@ -0,0 +1,16 @@ +INSERT INTO humidities ( + id, + value, + date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6) +ON CONFLICT (id) +DO + UPDATE SET + value = EXCLUDED.value, + date = EXCLUDED.date, + sensor_id = EXCLUDED.sensor_id, + update_date = date('now'); \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/insertOrUpdatePressure.sql b/pkg/repository/db/sqlite3/insertOrUpdatePressure.sql new file mode 100644 index 0000000..430f8aa --- /dev/null +++ b/pkg/repository/db/sqlite3/insertOrUpdatePressure.sql @@ -0,0 +1,16 @@ +INSERT INTO pressures ( + id, + value, + date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6) +ON CONFLICT (id) +DO + UPDATE SET + value = EXCLUDED.value, + date = EXCLUDED.date, + sensor_id = EXCLUDED.sensor_id, + update_date = date('now'); \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/insertOrUpdateSensor.sql b/pkg/repository/db/sqlite3/insertOrUpdateSensor.sql new file mode 100644 index 0000000..2e87609 --- /dev/null +++ b/pkg/repository/db/sqlite3/insertOrUpdateSensor.sql @@ -0,0 +1,31 @@ +INSERT INTO sensors ( + sensor_id, + sensor_name, + sensor_location, + wire_id, + i2c_bus, + i2c_address, + gpio_number, + sensor_model, + sensor_enabled, + tick_duration, + device_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) +ON CONFLICT (sensor_id) +DO + UPDATE SET + sensor_name = EXCLUDED.sensor_name, + sensor_location = EXCLUDED.sensor_location, + wire_id = EXCLUDED.wire_id, + i2c_bus = EXCLUDED.i2c_bus, + i2c_address = EXCLUDED.i2c_address, + gpio_number = EXCLUDED.gpio_number, + sensor_model = EXCLUDED.sensor_model, + sensor_enabled = EXCLUDED.sensor_enabled, + tick_duration = EXCLUDED.tick_duration, + device_id = EXCLUDED.device_id, + creation_date = EXCLUDED.creation_date, + update_date = date('now'); diff --git a/pkg/repository/db/sqlite3/insertOrUpdateTemperature.sql b/pkg/repository/db/sqlite3/insertOrUpdateTemperature.sql new file mode 100644 index 0000000..cf1e4d6 --- /dev/null +++ b/pkg/repository/db/sqlite3/insertOrUpdateTemperature.sql @@ -0,0 +1,16 @@ +INSERT INTO temperatures ( + id, + value, + date, + sensor_id, + creation_date, + update_date +) +VALUES ($1, $2, $3, $4, $5, $6) +ON CONFLICT (id) +DO + UPDATE SET + value = EXCLUDED.value, + date = EXCLUDED.date, + sensor_id = EXCLUDED.sensor_id, + update_date = date('now'); \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/selectHumidity.sql b/pkg/repository/db/sqlite3/selectHumidity.sql index 78ebc28..7e8fa06 100644 --- a/pkg/repository/db/sqlite3/selectHumidity.sql +++ b/pkg/repository/db/sqlite3/selectHumidity.sql @@ -8,4 +8,4 @@ SELECT FROM humidities WHERE - humidity_id = $1 \ No newline at end of file + id = $1 \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/selectPressure.sql b/pkg/repository/db/sqlite3/selectPressure.sql index 08f8a71..fc295c2 100644 --- a/pkg/repository/db/sqlite3/selectPressure.sql +++ b/pkg/repository/db/sqlite3/selectPressure.sql @@ -8,4 +8,4 @@ SELECT FROM pressures WHERE - pressure_id = $1 \ No newline at end of file + id = $1 \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/selectTemperature.sql b/pkg/repository/db/sqlite3/selectTemperature.sql index 51ab33a..5696656 100644 --- a/pkg/repository/db/sqlite3/selectTemperature.sql +++ b/pkg/repository/db/sqlite3/selectTemperature.sql @@ -8,4 +8,4 @@ SELECT FROM temperatures WHERE - temperature_id = $1 \ No newline at end of file + id = $1 \ No newline at end of file diff --git a/pkg/repository/repository.go b/pkg/repository/repository.go index 64cbc0c..3227050 100644 --- a/pkg/repository/repository.go +++ b/pkg/repository/repository.go @@ -27,6 +27,21 @@ func (repo *Repository) AddMeasuredValues(measuredValues ...*types.MeasuredValue return repo.database.InsertMeasuredValues(context.Background(), measuredValues...) } +// AddOrUpdateDevices to the repository +func (repo *Repository) AddOrUpdateDevices(devices ...*types.Device) error { + return repo.database.InsertOrUpdateDevices(context.Background(), devices...) +} + +// AddOrUpdateMeasuredValues to the repository +func (repo *Repository) AddOrUpdateMeasuredValues(measuredValues ...*types.MeasuredValue) error { + return repo.database.InsertOrUpdateMeasuredValues(context.Background(), measuredValues...) +} + +// AddOrUpdateSensors to the repository +func (repo *Repository) AddOrUpdateSensors(sensors ...*types.Sensor) error { + return repo.database.InsertOrUpdateSensors(context.Background(), sensors...) +} + // AddSensors to the repository func (repo *Repository) AddSensors(sensors ...*types.Sensor) error { return repo.database.InsertSensors(context.Background(), sensors...) @@ -91,6 +106,16 @@ func (repo *Repository) GetDevices() ([]*types.Device, error) { return repo.database.SelectDevices(context.Background()) } +// GetHumidity returns a humidity value by id +func (repo *Repository) GetHumidity(humidityID string) (*types.MeasuredValue, error) { + return repo.database.SelectHumidity(context.Background(), humidityID) +} + +// GetPressure returns a pressure value by id +func (repo *Repository) GetPressure(pressureID string) (*types.MeasuredValue, error) { + return repo.database.SelectPressure(context.Background(), pressureID) +} + // GetSensor returns a sensor by his id. If no sensor has been found, the // function returns nil. func (repo *Repository) GetSensor(sensorID string) (*types.Sensor, error) { @@ -141,6 +166,11 @@ func (repo *Repository) GetSensorsByDeviceID(deviceID string) ([]*types.Sensor, return cachedSensors, nil } +// GetTemperature returns a temperature value by id +func (repo *Repository) GetTemperature(pressureID string) (*types.MeasuredValue, error) { + return repo.database.SelectTemperature(context.Background(), pressureID) +} + // RemoveDevices removes devices by their ids from the repository. Additional // all sensors and measured values, which are in relation with the device // respectively the sensors will also be deleted. diff --git a/pkg/repository/repository_test.go b/pkg/repository/repository_test.go index ee3b89e..560b631 100644 --- a/pkg/repository/repository_test.go +++ b/pkg/repository/repository_test.go @@ -135,7 +135,47 @@ func testBackend(t *testing.T, repo *repository.Repository) { device, err = repo.GetDevice(expectedDevice.ID) require.NoError(err) - // require.JSONEq(jsonEncoder(expectedDevice), jsonEncoder(device)) + require.NotEmpty(device) + require.Equal(expectedDevice.ID, device.ID) + require.Equal(expectedDevice.Name, device.Name) + require.Equal(expectedDevice.Location, device.Location) + + // Test: AddOrUpdateDevices + location = "MySweetLocation" + expectedDevice = &types.Device{ + ID: "9d8c59a5-7927-4a7c-ad48-dbf5405ffd68", + Name: "MySweetDevice", + Location: &location, + CreationDate: *timeNow(require), + } + err = repo.AddOrUpdateDevices(expectedDevice) + require.NoError(err) + + // time.Sleep(time.Minute * 10) + + device, err = repo.GetDevice(expectedDevice.ID) + require.NoError(err) + require.NotEmpty(device) + require.Equal(expectedDevice.ID, device.ID) + require.Equal(expectedDevice.Name, device.Name) + require.Equal(expectedDevice.Location, device.Location) + + location = "MyUglyLocation" + expectedDevice = &types.Device{ + ID: "9d8c59a5-7927-4a7c-ad48-dbf5405ffd68", + Name: "MyUglyDevice", + Location: &location, + CreationDate: *timeNow(require), + } + err = repo.AddOrUpdateDevices(expectedDevice) + require.NoError(err) + + device, err = repo.GetDevice(expectedDevice.ID) + require.NoError(err) + require.NotEmpty(device) + require.Equal(expectedDevice.ID, device.ID) + require.Equal(expectedDevice.Name, device.Name) + require.Equal(expectedDevice.Location, device.Location) var ( wireID = "50473fdc-f6ef-4227-b3c4-484d8e9c1323" @@ -293,6 +333,65 @@ func testBackend(t *testing.T, repo *repository.Repository) { require.NotNil(sensor) // require.JSONEq(jsonEncoder(expectedSensor), jsonEncoder(sensor)) + // Test: AddOrUpdateSensors + expectedSensor = &types.Sensor{ + ID: "9bba0e0a-e996-4242-966f-db21bab6752f", + Name: "b4ac3d0f-cef6-4e93-bd7b-e821ae5ab593", + Location: "HelloWorld", + I2CBus: nil, + I2CAddress: nil, + Model: "SDS011", + Enabled: true, + TickDuration: "6h", + DeviceID: "39b8f150-8abf-4539-9f16-7f68cedb1649", + CreationDate: *timeNow(require), + } + + err = repo.AddOrUpdateSensors(expectedSensor) + require.NoError(err) + + sensor, err = repo.GetSensor(expectedSensor.ID) + require.NoError(err) + require.NotEmpty(sensor) + require.Equal(expectedSensor.ID, sensor.ID) + require.Equal(expectedSensor.Name, sensor.Name) + require.Equal(expectedSensor.Location, sensor.Location) + require.Equal(expectedSensor.I2CBus, sensor.I2CBus) + require.Equal(expectedSensor.I2CAddress, sensor.I2CAddress) + require.Equal(expectedSensor.Model, sensor.Model) + require.Equal(expectedSensor.Enabled, sensor.Enabled) + require.Equal(expectedSensor.TickDuration, sensor.TickDuration) + require.Equal(expectedSensor.DeviceID, sensor.DeviceID) + + expectedSensor = &types.Sensor{ + ID: "9bba0e0a-e996-4242-966f-db21bab6752f", + Name: "MySweetSensor", + Location: "MySweetLocation", + I2CBus: nil, + I2CAddress: nil, + Model: "Jap", + Enabled: false, + TickDuration: "8h", + DeviceID: "39b8f150-8abf-4539-9f16-7f68cedb1649", + CreationDate: *timeNow(require), + } + + err = repo.AddOrUpdateSensors(expectedSensor) + require.NoError(err) + + sensor, err = repo.GetSensor(expectedSensor.ID) + require.NoError(err) + require.NotEmpty(sensor) + require.Equal(expectedSensor.ID, sensor.ID) + require.Equal(expectedSensor.Name, sensor.Name) + require.Equal(expectedSensor.Location, sensor.Location) + require.Equal(expectedSensor.I2CBus, sensor.I2CBus) + require.Equal(expectedSensor.I2CAddress, sensor.I2CAddress) + require.Equal(expectedSensor.Model, sensor.Model) + require.Equal(expectedSensor.Enabled, sensor.Enabled) + require.Equal(expectedSensor.TickDuration, sensor.TickDuration) + require.Equal(expectedSensor.DeviceID, sensor.DeviceID) + var ( expectedMeasuredValues = []*types.MeasuredValue{ { @@ -328,6 +427,97 @@ func testBackend(t *testing.T, repo *repository.Repository) { // Test: AddMeasuredValues err = repo.AddMeasuredValues(expectedMeasuredValues...) require.NoError(err) + + for i := range expectedMeasuredValues { + + var ( + err error + measuredValue *types.MeasuredValue + ) + + switch expectedMeasuredValues[i].ValueType { + case types.Humidity: + measuredValue, err = repo.GetHumidity(expectedMeasuredValues[i].ID) + require.NoError(err) + require.NotNil(measuredValue) + case types.Pressure: + measuredValue, err = repo.GetPressure(expectedMeasuredValues[i].ID) + require.NoError(err) + require.NotNil(measuredValue) + case types.Temperature: + measuredValue, err = repo.GetTemperature(expectedMeasuredValues[i].ID) + require.NoError(err) + require.NotNil(measuredValue) + } + + require.Equal(expectedMeasuredValues[i].ID, measuredValue.ID) + require.Equal(expectedMeasuredValues[i].Value, measuredValue.Value) + require.Equal(expectedMeasuredValues[i].ValueType, measuredValue.ValueType) + require.Equal(expectedMeasuredValues[i].SensorID, measuredValue.SensorID) + } + + // Test: AddOrUpdateMeasuredValues + expectedMeasuredValues = []*types.MeasuredValue{ + { + ID: "2e5a297a-3da0-46ae-89d2-0fcab0f1d5f7", + Value: 35, + ValueType: types.Humidity, + Date: *timeNow(require), + SensorID: "8c74397f-8e60-4c9d-960d-3197747cef9a", + CreationDate: *timeNow(require), + UpdateDate: timeNow(require), + }, + { + ID: "d69f1b62-0c6c-4058-b42c-4a2821bd220c", + Value: 37, + ValueType: types.Pressure, + Date: *timeNow(require), + SensorID: "8c74397f-8e60-4c9d-960d-3197747cef9a", + CreationDate: *timeNow(require), + UpdateDate: timeNow(require), + }, + { + ID: "ea945ae0-412b-4561-a191-1f8f1f909fa4", + Value: 35.4, + ValueType: types.Temperature, + Date: *timeNow(require), + SensorID: "8c74397f-8e60-4c9d-960d-3197747cef9a", + CreationDate: *timeNow(require), + UpdateDate: timeNow(require), + }, + } + + err = repo.AddOrUpdateMeasuredValues(expectedMeasuredValues...) + require.NoError(err) + + for i := range expectedMeasuredValues { + + var ( + err error + measuredValue *types.MeasuredValue + ) + + switch expectedMeasuredValues[i].ValueType { + case types.Humidity: + measuredValue, err = repo.GetHumidity(expectedMeasuredValues[i].ID) + require.NoError(err) + require.NotNil(measuredValue) + case types.Pressure: + measuredValue, err = repo.GetPressure(expectedMeasuredValues[i].ID) + require.NoError(err) + require.NotNil(measuredValue) + case types.Temperature: + measuredValue, err = repo.GetTemperature(expectedMeasuredValues[i].ID) + require.NoError(err) + require.NotNil(measuredValue) + } + + require.Equal(expectedMeasuredValues[i].ID, measuredValue.ID) + require.Equal(expectedMeasuredValues[i].Value, measuredValue.Value) + require.Equal(expectedMeasuredValues[i].ValueType, measuredValue.ValueType) + require.Equal(expectedMeasuredValues[i].SensorID, measuredValue.SensorID) + } + } func jsonEncoder(v interface{}) string {