diff --git a/pkg/repository/postgres/postgres.go b/pkg/repository/postgres/postgres.go index 23d3fb5..c959e13 100644 --- a/pkg/repository/postgres/postgres.go +++ b/pkg/repository/postgres/postgres.go @@ -112,128 +112,6 @@ type Postgres struct { flogger logger.Logger } -// Close closes the database and prevents new queries from starting. Close then -// waits for all queries that have started processing on the server to finish. -func (postgres *Postgres) Close() error { - return postgres.dbo.Close() -} - -// RemoveDevices from the database -func (postgres *Postgres) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error { - f, err := postgresDMLAssets.ReadFile(deleteDeviceByIDSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", deleteDeviceByIDSQLFile, err) - } - - tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %v", err) - } - defer stmt.Close() - - for _, deviceID := range deviceIDs { - _, err = stmt.Exec(deviceID) - if err != nil { - return err - } - } - - return tx.Commit() -} - -// RemoveDevices from the database -func (postgres *Postgres) RemoveDevicesByNames(ctx context.Context, names ...string) error { - f, err := postgresDMLAssets.ReadFile(deleteDeviceByNameSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", deleteDeviceByNameSQLFile, err) - } - - tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %v", err) - } - defer stmt.Close() - - for _, deviceID := range names { - _, err = stmt.Exec(deviceID) - if err != nil { - return err - } - } - - return tx.Commit() -} - -// RemoveSensors from the database -func (postgres *Postgres) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...string) error { - f, err := postgresDMLAssets.ReadFile(deleteSensorByIDSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", deleteSensorByIDSQLFile, err) - } - - tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %v", err) - } - defer stmt.Close() - - for _, sensorID := range sensorIDs { - _, err = stmt.Exec(sensorID) - if err != nil { - return err - } - } - - return tx.Commit() -} - -// RemoveSensors from the database -func (postgres *Postgres) RemoveSensorsByNames(ctx context.Context, sensorIDs ...string) error { - f, err := postgresDMLAssets.ReadFile(deleteSensorByNameSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", deleteSensorByNameSQLFile, err) - } - - tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %v", err) - } - defer stmt.Close() - - for _, sensorID := range sensorIDs { - _, err = stmt.Exec(sensorID) - if err != nil { - return err - } - } - - return tx.Commit() -} - // AddDevices into the database func (postgres *Postgres) AddDevices(ctx context.Context, devices ...*types.Device) error { tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) @@ -283,6 +161,45 @@ func (postgres *Postgres) insertDevices(tx *sql.Tx, devices ...*types.Device) er return nil } +func (postgres *Postgres) AddOrUpdateDevices(ctx context.Context, devices ...*types.Device) error { + f, err := postgresDMLAssets.ReadFile(insertOrUpdateDeviceSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", insertOrUpdateDeviceSQLFile, err) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %w", err) + } + defer stmt.Close() + + for _, device := range devices { + + if device.CreationDate.Equal(time.Time{}) { + device.CreationDate = time.Now() + } + + _, err = stmt.Exec( + &device.ID, + &device.Name, + &device.Location, + &device.CreationDate, + &device.UpdateDate, + ) + if err != nil { + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return tx.Commit() +} + // AddMeasuredValues into the database func (postgres *Postgres) AddMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error { splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0) @@ -359,45 +276,6 @@ func (postgres *Postgres) AddMeasuredValues(ctx context.Context, measuredValues return tx.Commit() } -func (postgres *Postgres) AddOrUpdateDevices(ctx context.Context, devices ...*types.Device) error { - f, err := postgresDMLAssets.ReadFile(insertOrUpdateDeviceSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", insertOrUpdateDeviceSQLFile, err) - } - - tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %w", err) - } - defer stmt.Close() - - for _, device := range devices { - - if device.CreationDate.Equal(time.Time{}) { - device.CreationDate = time.Now() - } - - _, err = stmt.Exec( - &device.ID, - &device.Name, - &device.Location, - &device.CreationDate, - &device.UpdateDate, - ) - if err != nil { - return fmt.Errorf("Failed to execute statement: %v", err) - } - } - - return tx.Commit() -} - // AddOrUpdateMeasuredValues into the database func (postgres *Postgres) AddOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error { splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0) @@ -474,6 +352,54 @@ func (postgres *Postgres) AddOrUpdateMeasuredValues(ctx context.Context, measure return tx.Commit() } +// AddSensors into the database +func (postgres *Postgres) AddSensors(ctx context.Context, sensors ...*types.Sensor) error { + f, err := postgresDMLAssets.ReadFile(insertSensorSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", insertSensorSQLFile, err) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + 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 { + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return tx.Commit() +} + // AddOrUpdateSensors into the database func (postgres *Postgres) AddOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error { f, err := postgresDMLAssets.ReadFile(insertOrUpdateSensorSQLFile) @@ -522,52 +448,10 @@ func (postgres *Postgres) AddOrUpdateSensors(ctx context.Context, sensors ...*ty return tx.Commit() } -// AddSensors into the database -func (postgres *Postgres) AddSensors(ctx context.Context, sensors ...*types.Sensor) error { - f, err := postgresDMLAssets.ReadFile(insertSensorSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", insertSensorSQLFile, err) - } - - tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - 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 { - return fmt.Errorf("Failed to execute statement: %v", err) - } - } - - return tx.Commit() +// Close closes the database and prevents new queries from starting. Close then +// waits for all queries that have started processing on the server to finish. +func (postgres *Postgres) Close() error { + return postgres.dbo.Close() } // Migrate creates all required tables if not exist @@ -1122,6 +1006,122 @@ func (postgres *Postgres) GetTemperatures(ctx context.Context) ([]*types.Measure return measuredValues, nil } +// RemoveDevices from the database +func (postgres *Postgres) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error { + f, err := postgresDMLAssets.ReadFile(deleteDeviceByIDSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", deleteDeviceByIDSQLFile, err) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, deviceID := range deviceIDs { + _, err = stmt.Exec(deviceID) + if err != nil { + return err + } + } + + return tx.Commit() +} + +// RemoveDevices from the database +func (postgres *Postgres) RemoveDevicesByNames(ctx context.Context, names ...string) error { + f, err := postgresDMLAssets.ReadFile(deleteDeviceByNameSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", deleteDeviceByNameSQLFile, err) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, deviceID := range names { + _, err = stmt.Exec(deviceID) + if err != nil { + return err + } + } + + return tx.Commit() +} + +// RemoveSensors from the database +func (postgres *Postgres) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...string) error { + f, err := postgresDMLAssets.ReadFile(deleteSensorByIDSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", deleteSensorByIDSQLFile, err) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, sensorID := range sensorIDs { + _, err = stmt.Exec(sensorID) + if err != nil { + return err + } + } + + return tx.Commit() +} + +// RemoveSensors from the database +func (postgres *Postgres) RemoveSensorsByNames(ctx context.Context, sensorIDs ...string) error { + f, err := postgresDMLAssets.ReadFile(deleteSensorByNameSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", deleteSensorByNameSQLFile, err) + } + + tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, sensorID := range sensorIDs { + _, err = stmt.Exec(sensorID) + if err != nil { + return err + } + } + + return tx.Commit() +} + // UpdateDevices updates a device in the database func (postgres *Postgres) UpdateDevices(ctx context.Context, devices ...*types.Device) error { f, err := postgresDMLAssets.ReadFile(updateDeviceSQLFile) diff --git a/pkg/repository/sqlite3/sqlite.go b/pkg/repository/sqlite3/sqlite.go index 1392b1f..2704b24 100644 --- a/pkg/repository/sqlite3/sqlite.go +++ b/pkg/repository/sqlite3/sqlite.go @@ -130,142 +130,6 @@ type SQLite struct { mutex *sync.Mutex } -// Close closes the database and prevents new queries from starting. Close then -// waits for all queries that have started processing on the server to finish. -func (sqlite *SQLite) Close() error { - sqlite.mutex.Lock() - defer sqlite.mutex.Unlock() - return sqlite.dbo.Close() -} - -// RemoveDevices from the database -func (sqlite *SQLite) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error { - sqlite.mutex.Lock() - defer sqlite.mutex.Unlock() - - f, err := sqlite3DMLAssets.ReadFile(deleteDeviceByIDSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", deleteDeviceByIDSQLFile, err) - } - - tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %v", err) - } - defer stmt.Close() - - for _, deviceID := range deviceIDs { - _, err = stmt.Exec(deviceID) - if err != nil { - return err - } - } - - return tx.Commit() -} - -// RemoveDevices from the database -func (sqlite *SQLite) RemoveDevicesByNames(ctx context.Context, names ...string) error { - sqlite.mutex.Lock() - defer sqlite.mutex.Unlock() - - f, err := sqlite3DMLAssets.ReadFile(deleteDeviceByNameSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", deleteDeviceByNameSQLFile, err) - } - - tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %v", err) - } - defer stmt.Close() - - for _, deviceID := range names { - _, err = stmt.Exec(deviceID) - if err != nil { - return err - } - } - - return tx.Commit() -} - -// RemoveSensors from the database -func (sqlite *SQLite) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...string) error { - sqlite.mutex.Lock() - defer sqlite.mutex.Unlock() - - f, err := sqlite3DMLAssets.ReadFile(deleteSensorByIDSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", deleteSensorByIDSQLFile, err) - } - - tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %v", err) - } - defer stmt.Close() - - for _, sensorID := range sensorIDs { - _, err = stmt.Exec(sensorID) - if err != nil { - return err - } - } - - return tx.Commit() -} - -// RemoveSensors from the database -func (sqlite *SQLite) RemoveSensorsByNames(ctx context.Context, names ...string) error { - sqlite.mutex.Lock() - defer sqlite.mutex.Unlock() - - f, err := sqlite3DMLAssets.ReadFile(deleteSensorByNameSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", deleteSensorByNameSQLFile, err) - } - - tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - if err != nil { - return fmt.Errorf("Failed to prepare statement: %v", err) - } - defer stmt.Close() - - for _, sensorID := range names { - _, err = stmt.Exec(sensorID) - if err != nil { - return err - } - } - - return tx.Commit() -} - // AddDevices into the database func (sqlite *SQLite) AddDevices(ctx context.Context, devices ...*types.Device) error { sqlite.mutex.Lock() @@ -298,6 +162,38 @@ func (sqlite *SQLite) AddDevices(ctx context.Context, devices ...*types.Device) return tx.Commit() } +// AddOrUpdateDevices into the database +func (sqlite *SQLite) AddOrUpdateDevices(ctx context.Context, devices ...*types.Device) error { + sqlite.mutex.Lock() + defer sqlite.mutex.Unlock() + + f, err := sqlite3DMLAssets.ReadFile(insertOrUpdateDeviceSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", insertOrUpdateDeviceSQLFile, err) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + 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 { + return fmt.Errorf("Failed to execute statement: %v", err) + } + } + + return tx.Commit() +} + // AddMeasuredValues into the database func (sqlite *SQLite) AddMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error { sqlite.mutex.Lock() @@ -446,14 +342,14 @@ func (sqlite *SQLite) AddOrUpdateMeasuredValues(ctx context.Context, measuredVal return tx.Commit() } -// AddOrUpdateDevices into the database -func (sqlite *SQLite) AddOrUpdateDevices(ctx context.Context, devices ...*types.Device) error { +// AddSensors into the database +func (sqlite *SQLite) AddSensors(ctx context.Context, sensors ...*types.Sensor) error { sqlite.mutex.Lock() defer sqlite.mutex.Unlock() - f, err := sqlite3DMLAssets.ReadFile(insertOrUpdateDeviceSQLFile) + f, err := sqlite3DMLAssets.ReadFile(insertSensorSQLFile) if err != nil { - return fmt.Errorf("Failed to read file %v: %w", insertOrUpdateDeviceSQLFile, err) + return fmt.Errorf("Failed to read file %v: %w", insertSensorSQLFile, err) } tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) @@ -468,8 +364,22 @@ func (sqlite *SQLite) AddOrUpdateDevices(ctx context.Context, devices ...*types. } defer stmt.Close() - for _, device := range devices { - _, err = stmt.Exec(&device.ID, &device.Name, &device.Location, &device.CreationDate, &device.UpdateDate) + 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 { return fmt.Errorf("Failed to execute statement: %v", err) } @@ -524,50 +434,12 @@ func (sqlite *SQLite) AddOrUpdateSensors(ctx context.Context, sensors ...*types. return tx.Commit() } -// AddSensors into the database -func (sqlite *SQLite) AddSensors(ctx context.Context, sensors ...*types.Sensor) error { +// Close closes the database and prevents new queries from starting. Close then +// waits for all queries that have started processing on the server to finish. +func (sqlite *SQLite) Close() error { sqlite.mutex.Lock() defer sqlite.mutex.Unlock() - - f, err := sqlite3DMLAssets.ReadFile(insertSensorSQLFile) - if err != nil { - return fmt.Errorf("Failed to read file %v: %w", insertSensorSQLFile, err) - } - - tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) - if err != nil { - return fmt.Errorf("Failed to begin new transaction: %v", err) - } - defer tx.Rollback() - - stmt, err := tx.Prepare(string(f)) - 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 { - return fmt.Errorf("Failed to execute statement: %v", err) - } - } - - return tx.Commit() + return sqlite.dbo.Close() } // Migrate creates all required tables if not exist @@ -1171,6 +1043,134 @@ func (sqlite *SQLite) GetTemperatures(ctx context.Context) ([]*types.MeasuredVal return measuredValues, nil } +// RemoveDevices from the database +func (sqlite *SQLite) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error { + sqlite.mutex.Lock() + defer sqlite.mutex.Unlock() + + f, err := sqlite3DMLAssets.ReadFile(deleteDeviceByIDSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", deleteDeviceByIDSQLFile, err) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, deviceID := range deviceIDs { + _, err = stmt.Exec(deviceID) + if err != nil { + return err + } + } + + return tx.Commit() +} + +// RemoveDevices from the database +func (sqlite *SQLite) RemoveDevicesByNames(ctx context.Context, names ...string) error { + sqlite.mutex.Lock() + defer sqlite.mutex.Unlock() + + f, err := sqlite3DMLAssets.ReadFile(deleteDeviceByNameSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", deleteDeviceByNameSQLFile, err) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, deviceID := range names { + _, err = stmt.Exec(deviceID) + if err != nil { + return err + } + } + + return tx.Commit() +} + +// RemoveSensors from the database +func (sqlite *SQLite) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...string) error { + sqlite.mutex.Lock() + defer sqlite.mutex.Unlock() + + f, err := sqlite3DMLAssets.ReadFile(deleteSensorByIDSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", deleteSensorByIDSQLFile, err) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, sensorID := range sensorIDs { + _, err = stmt.Exec(sensorID) + if err != nil { + return err + } + } + + return tx.Commit() +} + +// RemoveSensors from the database +func (sqlite *SQLite) RemoveSensorsByNames(ctx context.Context, names ...string) error { + sqlite.mutex.Lock() + defer sqlite.mutex.Unlock() + + f, err := sqlite3DMLAssets.ReadFile(deleteSensorByNameSQLFile) + if err != nil { + return fmt.Errorf("Failed to read file %v: %w", deleteSensorByNameSQLFile, err) + } + + tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false}) + if err != nil { + return fmt.Errorf("Failed to begin new transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare(string(f)) + if err != nil { + return fmt.Errorf("Failed to prepare statement: %v", err) + } + defer stmt.Close() + + for _, sensorID := range names { + _, err = stmt.Exec(sensorID) + if err != nil { + return err + } + } + + return tx.Commit() +} + // UpdateDevices updates a device in the database func (sqlite *SQLite) UpdateDevices(ctx context.Context, devices ...*types.Device) error { sqlite.mutex.Lock()