feat: import from sqlite or postgres
This commit is contained in:
		
							
								
								
									
										114
									
								
								cli/imp/imp.go
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								cli/imp/imp.go
									
									
									
									
									
								
							@@ -1,6 +1,13 @@
 | 
				
			|||||||
package imp
 | 
					package imp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.cryptic.systems/volker.raschek/flucky/pkg/config"
 | 
				
			||||||
 | 
						"git.cryptic.systems/volker.raschek/flucky/pkg/repository"
 | 
				
			||||||
 | 
						"git.cryptic.systems/volker.raschek/go-logger"
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,61 +22,74 @@ func InitCmd(cmd *cobra.Command) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	importCmd := &cobra.Command{
 | 
						importCmd := &cobra.Command{
 | 
				
			||||||
		Use:   "import",
 | 
							Use:   "import",
 | 
				
			||||||
 | 
							Args:  cobra.RangeArgs(1, 2),
 | 
				
			||||||
		Short: "Import data from passed URL",
 | 
							Short: "Import data from passed URL",
 | 
				
			||||||
 | 
							Example: `import sqlite3:///var/cache/flucky/sqlite3.db
 | 
				
			||||||
 | 
					import sqlite3:///var/cache/flucky/sqlite3.db postgres://user:password@host:port/database?sslmode=disable`,
 | 
				
			||||||
		RunE: importSources,
 | 
							RunE: importSources,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	importCmd.Flags().BoolVar(&importSensors, "sensors", true, "Import sensors")
 | 
					 | 
				
			||||||
	importCmd.Flags().BoolVar(&importHumidities, "humidities", true, "Import humidities")
 | 
					 | 
				
			||||||
	importCmd.Flags().BoolVar(&importPressures, "pressures", true, "Import pressures")
 | 
					 | 
				
			||||||
	importCmd.Flags().BoolVar(&importTemperatures, "temperatures", true, "Import temperatures")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cmd.AddCommand(importCmd)
 | 
						cmd.AddCommand(importCmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func importSources(cmd *cobra.Command, args []string) error {
 | 
					func importSources(cmd *cobra.Command, args []string) error {
 | 
				
			||||||
	// configFile, err := cmd.Flags().GetString("config")
 | 
					 | 
				
			||||||
	// if err != nil {
 | 
					 | 
				
			||||||
	// 	return fmt.Errorf("No config file defined")
 | 
					 | 
				
			||||||
	// }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// cnf, err := config.Read(configFile)
 | 
						configFile, err := cmd.Flags().GetString("config")
 | 
				
			||||||
	// if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
	// 	return err
 | 
							return fmt.Errorf("No config file defined")
 | 
				
			||||||
	// }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// destURL, err := url.Parse(cnf.DSN)
 | 
						cnf, err := config.Read(configFile)
 | 
				
			||||||
	// if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
	// 	return err
 | 
							return err
 | 
				
			||||||
	// }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// logLevelString, err := cmd.Flags().GetString("loglevel")
 | 
						logLevelString, err := cmd.Flags().GetString("loglevel")
 | 
				
			||||||
	// if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
	// 	return err
 | 
							return err
 | 
				
			||||||
	// }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// logLevel, err := logger.ParseLogLevel(logLevelString)
 | 
						logLevel, err := logger.ParseLogLevel(logLevelString)
 | 
				
			||||||
	// if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
	// 	return err
 | 
							return err
 | 
				
			||||||
	// }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// flogger := logger.NewLogger(logLevel)
 | 
						flogger := logger.NewLogger(logLevel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// sourceURL, err := url.Parse(args[0])
 | 
						var (
 | 
				
			||||||
	// if err != nil {
 | 
							srcURL  *url.URL
 | 
				
			||||||
	// 	return fmt.Errorf("Failed to parse source url: %w", err)
 | 
							destURL *url.URL
 | 
				
			||||||
	// }
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// err = repository.Import(sourceURL, destURL, flogger, repository.OptImport{
 | 
						srcURL, err = url.Parse(args[0])
 | 
				
			||||||
	// 	Sensors:      importSensors,
 | 
						if err != nil {
 | 
				
			||||||
	// 	Humidities:   importHumidities,
 | 
							return err
 | 
				
			||||||
	// 	Pressures:    importPressures,
 | 
						}
 | 
				
			||||||
	// 	Temperatures: importTemperatures,
 | 
					
 | 
				
			||||||
	// })
 | 
						switch len(args) {
 | 
				
			||||||
	// if err != nil {
 | 
						case 1:
 | 
				
			||||||
	// 	return fmt.Errorf("Failed to import: %w", err)
 | 
							destURL, err = url.Parse(cnf.DSN)
 | 
				
			||||||
	// }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
	return nil
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 2:
 | 
				
			||||||
 | 
							destURL, err = url.Parse(args[1])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						srcRepository, err := repository.New(srcURL, flogger)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						destRepository, err := repository.New(destURL, flogger)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return destRepository.Import(context.Background(), srcRepository)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,121 +1,26 @@
 | 
				
			|||||||
package postgres
 | 
					package repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"database/sql"
 | 
						"database/sql"
 | 
				
			||||||
	"embed"
 | 
					 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.cryptic.systems/volker.raschek/flucky/pkg/repository/postgres"
 | 
				
			||||||
	"git.cryptic.systems/volker.raschek/flucky/pkg/types"
 | 
						"git.cryptic.systems/volker.raschek/flucky/pkg/types"
 | 
				
			||||||
	"git.cryptic.systems/volker.raschek/go-logger"
 | 
						"git.cryptic.systems/volker.raschek/go-logger"
 | 
				
			||||||
	"github.com/golang-migrate/migrate/v4"
 | 
						"github.com/golang-migrate/migrate/v4"
 | 
				
			||||||
	"github.com/johejo/golang-migrate-extra/source/iofs"
 | 
						"github.com/johejo/golang-migrate-extra/source/iofs"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					type PostgresOpts struct {
 | 
				
			||||||
	//go:embed ddl/*.sql
 | 
					 | 
				
			||||||
	ddlAssets embed.FS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/deleteDeviceByID.sql
 | 
					 | 
				
			||||||
	deleteDeviceByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/deleteDeviceByName.sql
 | 
					 | 
				
			||||||
	deleteDeviceByNameSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/deleteSensorByID.sql
 | 
					 | 
				
			||||||
	deleteSensorByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/deleteSensorByName.sql
 | 
					 | 
				
			||||||
	deleteSensorByNameSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertDevice.sql
 | 
					 | 
				
			||||||
	insertDeviceSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertHumidity.sql
 | 
					 | 
				
			||||||
	insertHumiditySQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdateDevice.sql
 | 
					 | 
				
			||||||
	insertOrUpdateDeviceSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdateHumidity.sql
 | 
					 | 
				
			||||||
	insertOrUpdateHumiditySQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdatePressure.sql
 | 
					 | 
				
			||||||
	insertOrUpdatePressureSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdateSensor.sql
 | 
					 | 
				
			||||||
	insertOrUpdateSensorSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdateTemperature.sql
 | 
					 | 
				
			||||||
	insertOrUpdateTemperatureSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertPressure.sql
 | 
					 | 
				
			||||||
	insertPressureSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertSensor.sql
 | 
					 | 
				
			||||||
	insertSensorSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertTemperature.sql
 | 
					 | 
				
			||||||
	insertTemperatureSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectDeviceByID.sql
 | 
					 | 
				
			||||||
	selectDeviceByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectDeviceByName.sql
 | 
					 | 
				
			||||||
	selectDeviceByNameSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectDevices.sql
 | 
					 | 
				
			||||||
	selectDevicesSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectHumidities.sql
 | 
					 | 
				
			||||||
	selectHumiditiesSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectHumidityByID.sql
 | 
					 | 
				
			||||||
	selectHumidityByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectPressureByID.sql
 | 
					 | 
				
			||||||
	selectPressureByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectPressures.sql
 | 
					 | 
				
			||||||
	selectPressuresSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensorByID.sql
 | 
					 | 
				
			||||||
	selectSensorByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensors.sql
 | 
					 | 
				
			||||||
	selectSensorsSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensorsByDeviceID.sql
 | 
					 | 
				
			||||||
	selectSensorsByDeviceIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensorsByModel.sql
 | 
					 | 
				
			||||||
	selectSensorsByModelSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensorsByName.sql
 | 
					 | 
				
			||||||
	selectSensorsByNameSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectTemperatureByID.sql
 | 
					 | 
				
			||||||
	selectTemperatureByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectTemperatures.sql
 | 
					 | 
				
			||||||
	selectTemperaturesSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/updateDevice.sql
 | 
					 | 
				
			||||||
	updateDeviceSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/updateSensor.sql
 | 
					 | 
				
			||||||
	updateSensorSQL string
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Opts struct {
 | 
					 | 
				
			||||||
	DatabaseURL *url.URL
 | 
						DatabaseURL *url.URL
 | 
				
			||||||
	Logger      logger.Logger
 | 
						Logger      logger.Logger
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (o *Opts) Validate() error {
 | 
					func (o *PostgresOpts) Validate() error {
 | 
				
			||||||
	for k, v := range map[string]interface{}{
 | 
						for k, v := range map[string]interface{}{
 | 
				
			||||||
		"DatabaseURL": o.DatabaseURL,
 | 
							"DatabaseURL": o.DatabaseURL,
 | 
				
			||||||
		"Logger":      o.Logger,
 | 
							"Logger":      o.Logger,
 | 
				
			||||||
@@ -132,7 +37,7 @@ func (o *Opts) Validate() error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func New(opts Opts) (*Postgres, error) {
 | 
					func NewPostgres(opts PostgresOpts) (Repository, error) {
 | 
				
			||||||
	if err := opts.Validate(); err != nil {
 | 
						if err := opts.Validate(); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -157,14 +62,14 @@ type Postgres struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddDevices into the database
 | 
					// AddDevices into the database
 | 
				
			||||||
func (postgres *Postgres) AddDevices(ctx context.Context, devices ...*types.Device) error {
 | 
					func (d *Postgres) AddDevices(ctx context.Context, devices ...*types.Device) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = postgres.insertDevices(tx, devices...)
 | 
						err = d.insertDevices(tx, devices...)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -172,8 +77,8 @@ func (postgres *Postgres) AddDevices(ctx context.Context, devices ...*types.Devi
 | 
				
			|||||||
	return tx.Commit()
 | 
						return tx.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (postgres *Postgres) insertDevices(tx *sql.Tx, devices ...*types.Device) error {
 | 
					func (d *Postgres) insertDevices(tx *sql.Tx, devices ...*types.Device) error {
 | 
				
			||||||
	stmt, err := tx.Prepare(insertDeviceSQL)
 | 
						stmt, err := tx.Prepare(postgres.InsertDeviceSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -200,14 +105,23 @@ func (postgres *Postgres) insertDevices(tx *sql.Tx, devices ...*types.Device) er
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (postgres *Postgres) AddOrUpdateDevices(ctx context.Context, devices ...*types.Device) error {
 | 
					func (d *Postgres) AddOrUpdateDevices(ctx context.Context, devices ...*types.Device) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(insertOrUpdateDeviceSQL)
 | 
						err = d.insertOrUpdateDevices(tx, devices...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *Postgres) insertOrUpdateDevices(tx *sql.Tx, devices ...*types.Device) error {
 | 
				
			||||||
 | 
						stmt, err := tx.Prepare(postgres.InsertOrUpdateDeviceSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %w", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -231,11 +145,11 @@ func (postgres *Postgres) AddOrUpdateDevices(ctx context.Context, devices ...*ty
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return tx.Commit()
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddMeasuredValues into the database
 | 
					// AddMeasuredValues into the database
 | 
				
			||||||
func (postgres *Postgres) AddMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error {
 | 
					func (d *Postgres) AddMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error {
 | 
				
			||||||
	splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0)
 | 
						splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, measuredValue := range measuredValues {
 | 
						for _, measuredValue := range measuredValues {
 | 
				
			||||||
@@ -245,14 +159,36 @@ func (postgres *Postgres) AddMeasuredValues(ctx context.Context, measuredValues
 | 
				
			|||||||
		splittedMeasuredValues[measuredValue.ValueType] = append(splittedMeasuredValues[measuredValue.ValueType], measuredValue)
 | 
							splittedMeasuredValues[measuredValue.ValueType] = append(splittedMeasuredValues[measuredValue.ValueType], measuredValue)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// General insert function
 | 
						for measuredValueType, measuredValues := range splittedMeasuredValues {
 | 
				
			||||||
	insert := func(tx *sql.Tx, query string, measuredValues []*types.MeasuredValue) error {
 | 
							var queryFile string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch measuredValueType {
 | 
				
			||||||
 | 
							case types.Humidity:
 | 
				
			||||||
 | 
								queryFile = postgres.InsertHumiditySQL
 | 
				
			||||||
 | 
							case types.Pressure:
 | 
				
			||||||
 | 
								queryFile = postgres.InsertPressureSQL
 | 
				
			||||||
 | 
							case types.Temperature:
 | 
				
			||||||
 | 
								queryFile = postgres.InsertTemperatureSQL
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return fmt.Errorf("Measured value type %v not supported", measuredValueType)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err := d.insertMeasuredValues(tx, queryFile, measuredValues...)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *Postgres) insertMeasuredValues(tx *sql.Tx, query string, measuredValues ...*types.MeasuredValue) error {
 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
@@ -282,31 +218,8 @@ func (postgres *Postgres) AddMeasuredValues(ctx context.Context, measuredValues
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for measuredValueType, measuredValues := range splittedMeasuredValues {
 | 
					 | 
				
			||||||
		var queryFile string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch measuredValueType {
 | 
					 | 
				
			||||||
		case types.Humidity:
 | 
					 | 
				
			||||||
			queryFile = insertHumiditySQL
 | 
					 | 
				
			||||||
		case types.Pressure:
 | 
					 | 
				
			||||||
			queryFile = insertPressureSQL
 | 
					 | 
				
			||||||
		case types.Temperature:
 | 
					 | 
				
			||||||
			queryFile = insertTemperatureSQL
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return fmt.Errorf("Measured value type %v not supported", measuredValueType)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		err := insert(tx, queryFile, measuredValues)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return tx.Commit()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AddOrUpdateMeasuredValues into the database
 | 
					// AddOrUpdateMeasuredValues into the database
 | 
				
			||||||
func (postgres *Postgres) AddOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error {
 | 
					func (d *Postgres) AddOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error {
 | 
				
			||||||
	splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0)
 | 
						splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, measuredValue := range measuredValues {
 | 
						for _, measuredValue := range measuredValues {
 | 
				
			||||||
@@ -316,14 +229,36 @@ func (postgres *Postgres) AddOrUpdateMeasuredValues(ctx context.Context, measure
 | 
				
			|||||||
		splittedMeasuredValues[measuredValue.ValueType] = append(splittedMeasuredValues[measuredValue.ValueType], measuredValue)
 | 
							splittedMeasuredValues[measuredValue.ValueType] = append(splittedMeasuredValues[measuredValue.ValueType], measuredValue)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// General insert function
 | 
						for measuredValueType, measuredValues := range splittedMeasuredValues {
 | 
				
			||||||
	insert := func(tx *sql.Tx, query string, measuredValues []*types.MeasuredValue) error {
 | 
							var queryFile string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch measuredValueType {
 | 
				
			||||||
 | 
							case types.Humidity:
 | 
				
			||||||
 | 
								queryFile = postgres.InsertOrUpdateHumiditySQL
 | 
				
			||||||
 | 
							case types.Pressure:
 | 
				
			||||||
 | 
								queryFile = postgres.InsertOrUpdatePressureSQL
 | 
				
			||||||
 | 
							case types.Temperature:
 | 
				
			||||||
 | 
								queryFile = postgres.InsertOrUpdateTemperatureSQL
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return fmt.Errorf("Measured value type %v not supported", measuredValueType)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err := d.insertOrUpdateMeasuredValues(tx, queryFile, measuredValues...)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *Postgres) insertOrUpdateMeasuredValues(tx *sql.Tx, query string, measuredValues ...*types.MeasuredValue) error {
 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
@@ -353,38 +288,15 @@ func (postgres *Postgres) AddOrUpdateMeasuredValues(ctx context.Context, measure
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for measuredValueType, measuredValues := range splittedMeasuredValues {
 | 
					 | 
				
			||||||
		var queryFile string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch measuredValueType {
 | 
					 | 
				
			||||||
		case types.Humidity:
 | 
					 | 
				
			||||||
			queryFile = insertOrUpdateHumiditySQL
 | 
					 | 
				
			||||||
		case types.Pressure:
 | 
					 | 
				
			||||||
			queryFile = insertOrUpdatePressureSQL
 | 
					 | 
				
			||||||
		case types.Temperature:
 | 
					 | 
				
			||||||
			queryFile = insertOrUpdateTemperatureSQL
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return fmt.Errorf("Measured value type %v not supported", measuredValueType)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		err := insert(tx, queryFile, measuredValues)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return tx.Commit()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AddSensors into the database
 | 
					// AddSensors into the database
 | 
				
			||||||
func (postgres *Postgres) AddSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
					func (d *Postgres) AddSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(insertSensorSQL)
 | 
						stmt, err := tx.Prepare(postgres.InsertSensorSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -420,14 +332,23 @@ func (postgres *Postgres) AddSensors(ctx context.Context, sensors ...*types.Sens
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddOrUpdateSensors into the database
 | 
					// AddOrUpdateSensors into the database
 | 
				
			||||||
func (postgres *Postgres) AddOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
					func (d *Postgres) AddOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(insertOrUpdateSensorSQL)
 | 
						err = d.insertOrUpdateSensors(tx, sensors...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *Postgres) insertOrUpdateSensors(tx *sql.Tx, sensors ...*types.Sensor) error {
 | 
				
			||||||
 | 
						stmt, err := tx.Prepare(postgres.InsertOrUpdateSensorSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -459,7 +380,7 @@ func (postgres *Postgres) AddOrUpdateSensors(ctx context.Context, sensors ...*ty
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return tx.Commit()
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Close closes the database and prevents new queries from starting. Close then
 | 
					// Close closes the database and prevents new queries from starting. Close then
 | 
				
			||||||
@@ -469,13 +390,13 @@ func (postgres *Postgres) Close() error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Migrate creates all required tables if not exist
 | 
					// Migrate creates all required tables if not exist
 | 
				
			||||||
func (postgres *Postgres) Migrate(ctx context.Context) error {
 | 
					func (d *Postgres) Migrate(ctx context.Context) error {
 | 
				
			||||||
	sourceDriver, err := iofs.New(ddlAssets, "ddl")
 | 
						sourceDriver, err := iofs.New(postgres.DDLAssets, postgres.DDLAssetPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m, err := migrate.NewWithSourceInstance("iofs", sourceDriver, postgres.databaseURL.String())
 | 
						m, err := migrate.NewWithSourceInstance("iofs", sourceDriver, d.databaseURL.String())
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -490,14 +411,14 @@ func (postgres *Postgres) Migrate(ctx context.Context) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDevice from database
 | 
					// GetDevice from database
 | 
				
			||||||
func (postgres *Postgres) GetDeviceByID(ctx context.Context, id string) (*types.Device, error) {
 | 
					func (d *Postgres) GetDeviceByID(ctx context.Context, id string) (*types.Device, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	devices, err := postgres.selectDevices(tx, selectDeviceByIDSQL, id)
 | 
						devices, err := d.selectDevices(tx, postgres.SelectDeviceByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -515,14 +436,14 @@ func (postgres *Postgres) GetDeviceByID(ctx context.Context, id string) (*types.
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDevice from database
 | 
					// GetDevice from database
 | 
				
			||||||
func (postgres *Postgres) GetDeviceByName(ctx context.Context, name string) (*types.Device, error) {
 | 
					func (d *Postgres) GetDeviceByName(ctx context.Context, name string) (*types.Device, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	devices, err := postgres.selectDevices(tx, selectDeviceByNameSQL, name)
 | 
						devices, err := d.selectDevices(tx, postgres.SelectDeviceByNameSQL, name)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -540,14 +461,14 @@ func (postgres *Postgres) GetDeviceByName(ctx context.Context, name string) (*ty
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDevices from the database
 | 
					// GetDevices from the database
 | 
				
			||||||
func (postgres *Postgres) GetDevices(ctx context.Context) ([]*types.Device, error) {
 | 
					func (d *Postgres) GetDevices(ctx context.Context) ([]*types.Device, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	devices, err := postgres.selectDevices(tx, selectDevicesSQL)
 | 
						devices, err := d.selectDevices(tx, postgres.SelectDevicesSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -560,7 +481,7 @@ func (postgres *Postgres) GetDevices(ctx context.Context) ([]*types.Device, erro
 | 
				
			|||||||
	return devices, nil
 | 
						return devices, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (postgres *Postgres) selectDevices(tx *sql.Tx, query string, args ...interface{}) ([]*types.Device, error) {
 | 
					func (d *Postgres) selectDevices(tx *sql.Tx, query string, args ...interface{}) ([]*types.Device, error) {
 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return nil, fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
@@ -592,14 +513,14 @@ func (postgres *Postgres) selectDevices(tx *sql.Tx, query string, args ...interf
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHumidity returns humidity from the database
 | 
					// GetHumidity returns humidity from the database
 | 
				
			||||||
func (postgres *Postgres) GetHumidityByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
					func (d *Postgres) GetHumidityByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := postgres.selectMeasuredValue(tx, selectHumidityByIDSQL, id)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, postgres.SelectHumidityByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -621,14 +542,14 @@ func (postgres *Postgres) GetHumidityByID(ctx context.Context, id string) (*type
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHumidities returns humidities from the database
 | 
					// GetHumidities returns humidities from the database
 | 
				
			||||||
func (postgres *Postgres) GetHumidities(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
					func (d *Postgres) GetHumidities(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := postgres.selectMeasuredValue(tx, selectHumiditiesSQL)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, postgres.SelectHumiditiesSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -645,7 +566,7 @@ func (postgres *Postgres) GetHumidities(ctx context.Context) ([]*types.MeasuredV
 | 
				
			|||||||
	return measuredValues, nil
 | 
						return measuredValues, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (postgres *Postgres) selectMeasuredValue(tx *sql.Tx, query string, args ...interface{}) ([]*types.MeasuredValue, error) {
 | 
					func (d *Postgres) selectMeasuredValue(tx *sql.Tx, query string, args ...interface{}) ([]*types.MeasuredValue, error) {
 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -680,14 +601,14 @@ func (postgres *Postgres) selectMeasuredValue(tx *sql.Tx, query string, args ...
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetPressure returns pressure from the database
 | 
					// GetPressure returns pressure from the database
 | 
				
			||||||
func (postgres *Postgres) GetPressureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
					func (d *Postgres) GetPressureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := postgres.selectMeasuredValue(tx, selectPressureByIDSQL, id)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, postgres.SelectPressureByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -709,14 +630,14 @@ func (postgres *Postgres) GetPressureByID(ctx context.Context, id string) (*type
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetPressures returns pressure from the database
 | 
					// GetPressures returns pressure from the database
 | 
				
			||||||
func (postgres *Postgres) GetPressures(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
					func (d *Postgres) GetPressures(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := postgres.selectMeasuredValue(tx, selectPressuresSQL)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, postgres.SelectPressuresSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -734,14 +655,14 @@ func (postgres *Postgres) GetPressures(ctx context.Context) ([]*types.MeasuredVa
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensor from database
 | 
					// GetSensor from database
 | 
				
			||||||
func (postgres *Postgres) GetSensorByID(ctx context.Context, id string) (*types.Sensor, error) {
 | 
					func (d *Postgres) GetSensorByID(ctx context.Context, id string) (*types.Sensor, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sensors, err := postgres.selectSensors(tx, selectSensorByIDSQL, id)
 | 
						sensors, err := d.selectSensors(tx, postgres.SelectSensorByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -759,14 +680,14 @@ func (postgres *Postgres) GetSensorByID(ctx context.Context, id string) (*types.
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensors from the database
 | 
					// GetSensors from the database
 | 
				
			||||||
func (postgres *Postgres) GetSensors(ctx context.Context) ([]*types.Sensor, error) {
 | 
					func (d *Postgres) GetSensors(ctx context.Context) ([]*types.Sensor, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sensors, err := postgres.selectSensors(tx, selectSensorsSQL)
 | 
						sensors, err := d.selectSensors(tx, postgres.SelectSensorsSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -780,8 +701,8 @@ func (postgres *Postgres) GetSensors(ctx context.Context) ([]*types.Sensor, erro
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensorsByModels from the database
 | 
					// GetSensorsByModels from the database
 | 
				
			||||||
func (postgres *Postgres) GetSensorsByDeviceIDs(ctx context.Context, deviceIDs ...string) ([]*types.Sensor, error) {
 | 
					func (d *Postgres) GetSensorsByDeviceIDs(ctx context.Context, deviceIDs ...string) ([]*types.Sensor, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -789,7 +710,7 @@ func (postgres *Postgres) GetSensorsByDeviceIDs(ctx context.Context, deviceIDs .
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cachedSensors := make([]*types.Sensor, 0)
 | 
						cachedSensors := make([]*types.Sensor, 0)
 | 
				
			||||||
	for i := range deviceIDs {
 | 
						for i := range deviceIDs {
 | 
				
			||||||
		sensors, err := postgres.selectSensors(tx, selectSensorsByDeviceIDSQL, deviceIDs[i])
 | 
							sensors, err := d.selectSensors(tx, postgres.SelectSensorsByDeviceIDSQL, deviceIDs[i])
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -806,15 +727,15 @@ func (postgres *Postgres) GetSensorsByDeviceIDs(ctx context.Context, deviceIDs .
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensorsByModel from the database
 | 
					// GetSensorsByModel from the database
 | 
				
			||||||
func (postgres *Postgres) GetSensorsByModels(ctx context.Context, sensorModels ...string) ([]*types.Sensor, error) {
 | 
					func (d *Postgres) GetSensorsByModels(ctx context.Context, sensorModels ...string) ([]*types.Sensor, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cachedSensors := make([]*types.Sensor, 0)
 | 
						cachedSensors := make([]*types.Sensor, 0)
 | 
				
			||||||
	for i := range sensorModels {
 | 
						for i := range sensorModels {
 | 
				
			||||||
		sensors, err := postgres.selectSensors(tx, selectSensorsByModelSQL, sensorModels[i])
 | 
							sensors, err := d.selectSensors(tx, postgres.SelectSensorsByModelSQL, sensorModels[i])
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -831,8 +752,8 @@ func (postgres *Postgres) GetSensorsByModels(ctx context.Context, sensorModels .
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensorsByModel from the database
 | 
					// GetSensorsByModel from the database
 | 
				
			||||||
func (postgres *Postgres) GetSensorsByNames(ctx context.Context, sensorNames ...string) ([]*types.Sensor, error) {
 | 
					func (d *Postgres) GetSensorsByNames(ctx context.Context, sensorNames ...string) ([]*types.Sensor, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -840,7 +761,7 @@ func (postgres *Postgres) GetSensorsByNames(ctx context.Context, sensorNames ...
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cachedSensors := make([]*types.Sensor, 0)
 | 
						cachedSensors := make([]*types.Sensor, 0)
 | 
				
			||||||
	for i := range sensorNames {
 | 
						for i := range sensorNames {
 | 
				
			||||||
		sensors, err := postgres.selectSensors(tx, selectSensorsByNameSQL, sensorNames[i])
 | 
							sensors, err := d.selectSensors(tx, postgres.SelectSensorsByNameSQL, sensorNames[i])
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -856,7 +777,7 @@ func (postgres *Postgres) GetSensorsByNames(ctx context.Context, sensorNames ...
 | 
				
			|||||||
	return cachedSensors, nil
 | 
						return cachedSensors, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (postgres *Postgres) selectSensors(tx *sql.Tx, query string, args ...interface{}) ([]*types.Sensor, error) {
 | 
					func (d *Postgres) selectSensors(tx *sql.Tx, query string, args ...interface{}) ([]*types.Sensor, error) {
 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return nil, fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
@@ -897,14 +818,14 @@ func (postgres *Postgres) selectSensors(tx *sql.Tx, query string, args ...interf
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetTemperature returns temperatures from the database
 | 
					// GetTemperature returns temperatures from the database
 | 
				
			||||||
func (postgres *Postgres) GetTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
					func (d *Postgres) GetTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := postgres.selectMeasuredValue(tx, selectTemperatureByIDSQL, id)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, postgres.SelectTemperatureByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -926,14 +847,14 @@ func (postgres *Postgres) GetTemperatureByID(ctx context.Context, id string) (*t
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetTemperatures returns temperatures from the database
 | 
					// GetTemperatures returns temperatures from the database
 | 
				
			||||||
func (postgres *Postgres) GetTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
					func (d *Postgres) GetTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := postgres.selectMeasuredValue(tx, selectTemperaturesSQL)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, postgres.SelectTemperaturesSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -950,15 +871,62 @@ func (postgres *Postgres) GetTemperatures(ctx context.Context) ([]*types.Measure
 | 
				
			|||||||
	return measuredValues, nil
 | 
						return measuredValues, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Import imports devices, sensors and all measured values from a source
 | 
				
			||||||
 | 
					// repository. Existing entries will be updated.
 | 
				
			||||||
 | 
					func (d *Postgres) Import(ctx context.Context, src Repository) error {
 | 
				
			||||||
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						devices, err := src.GetDevices(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = d.insertOrUpdateDevices(tx, devices...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sensors, err := src.GetSensors(ctx)
 | 
				
			||||||
 | 
						err = d.insertOrUpdateSensors(tx, sensors...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, value := range []struct {
 | 
				
			||||||
 | 
							f     func(ctx context.Context) ([]*types.MeasuredValue, error)
 | 
				
			||||||
 | 
							query string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{f: src.GetHumidities, query: postgres.InsertOrUpdateHumiditySQL},
 | 
				
			||||||
 | 
							{f: src.GetPressures, query: postgres.InsertOrUpdatePressureSQL},
 | 
				
			||||||
 | 
							{f: src.GetTemperatures, query: postgres.InsertOrUpdateTemperatureSQL},
 | 
				
			||||||
 | 
						} {
 | 
				
			||||||
 | 
							measuredValues, err := value.f(ctx)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = d.insertOrUpdateMeasuredValues(tx, value.query, measuredValues...)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveDevices from the database
 | 
					// RemoveDevices from the database
 | 
				
			||||||
func (postgres *Postgres) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error {
 | 
					func (d *Postgres) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(deleteDeviceByIDSQL)
 | 
						stmt, err := tx.Prepare(postgres.DeleteDeviceByIDSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -975,14 +943,14 @@ func (postgres *Postgres) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveDevices from the database
 | 
					// RemoveDevices from the database
 | 
				
			||||||
func (postgres *Postgres) RemoveDevicesByNames(ctx context.Context, names ...string) error {
 | 
					func (d *Postgres) RemoveDevicesByNames(ctx context.Context, names ...string) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(deleteDeviceByNameSQL)
 | 
						stmt, err := tx.Prepare(postgres.DeleteDeviceByNameSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -999,14 +967,14 @@ func (postgres *Postgres) RemoveDevicesByNames(ctx context.Context, names ...str
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveSensors from the database
 | 
					// RemoveSensors from the database
 | 
				
			||||||
func (postgres *Postgres) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...string) error {
 | 
					func (d *Postgres) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...string) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(deleteSensorByIDSQL)
 | 
						stmt, err := tx.Prepare(postgres.DeleteSensorByIDSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1023,14 +991,14 @@ func (postgres *Postgres) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveSensors from the database
 | 
					// RemoveSensors from the database
 | 
				
			||||||
func (postgres *Postgres) RemoveSensorsByNames(ctx context.Context, sensorIDs ...string) error {
 | 
					func (d *Postgres) RemoveSensorsByNames(ctx context.Context, sensorIDs ...string) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(deleteSensorByNameSQL)
 | 
						stmt, err := tx.Prepare(postgres.DeleteSensorByNameSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1047,14 +1015,14 @@ func (postgres *Postgres) RemoveSensorsByNames(ctx context.Context, sensorIDs ..
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateDevices updates a device in the database
 | 
					// UpdateDevices updates a device in the database
 | 
				
			||||||
func (postgres *Postgres) UpdateDevices(ctx context.Context, devices ...*types.Device) error {
 | 
					func (d *Postgres) UpdateDevices(ctx context.Context, devices ...*types.Device) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(updateDeviceSQL)
 | 
						stmt, err := tx.Prepare(postgres.UpdateDeviceSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1080,14 +1048,14 @@ func (postgres *Postgres) UpdateDevices(ctx context.Context, devices ...*types.D
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateSensors updates a sensor in the database
 | 
					// UpdateSensors updates a sensor in the database
 | 
				
			||||||
func (postgres *Postgres) UpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
					func (d *Postgres) UpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
				
			||||||
	tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(updateSensorSQL)
 | 
						stmt, err := tx.Prepare(postgres.UpdateSensorSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
							
								
								
									
										100
									
								
								pkg/repository/postgres/statements.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								pkg/repository/postgres/statements.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					package postgres
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "embed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						DDLAssetPath = "ddl"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed ddl/*.sql
 | 
				
			||||||
 | 
						DDLAssets embed.FS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/deleteDeviceByID.sql
 | 
				
			||||||
 | 
						DeleteDeviceByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/deleteDeviceByName.sql
 | 
				
			||||||
 | 
						DeleteDeviceByNameSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/deleteSensorByID.sql
 | 
				
			||||||
 | 
						DeleteSensorByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/deleteSensorByName.sql
 | 
				
			||||||
 | 
						DeleteSensorByNameSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertDevice.sql
 | 
				
			||||||
 | 
						InsertDeviceSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertHumidity.sql
 | 
				
			||||||
 | 
						InsertHumiditySQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdateDevice.sql
 | 
				
			||||||
 | 
						InsertOrUpdateDeviceSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdateHumidity.sql
 | 
				
			||||||
 | 
						InsertOrUpdateHumiditySQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdatePressure.sql
 | 
				
			||||||
 | 
						InsertOrUpdatePressureSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdateSensor.sql
 | 
				
			||||||
 | 
						InsertOrUpdateSensorSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdateTemperature.sql
 | 
				
			||||||
 | 
						InsertOrUpdateTemperatureSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertPressure.sql
 | 
				
			||||||
 | 
						InsertPressureSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertSensor.sql
 | 
				
			||||||
 | 
						InsertSensorSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertTemperature.sql
 | 
				
			||||||
 | 
						InsertTemperatureSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectDeviceByID.sql
 | 
				
			||||||
 | 
						SelectDeviceByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectDeviceByName.sql
 | 
				
			||||||
 | 
						SelectDeviceByNameSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectDevices.sql
 | 
				
			||||||
 | 
						SelectDevicesSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectHumidities.sql
 | 
				
			||||||
 | 
						SelectHumiditiesSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectHumidityByID.sql
 | 
				
			||||||
 | 
						SelectHumidityByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectPressureByID.sql
 | 
				
			||||||
 | 
						SelectPressureByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectPressures.sql
 | 
				
			||||||
 | 
						SelectPressuresSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensorByID.sql
 | 
				
			||||||
 | 
						SelectSensorByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensors.sql
 | 
				
			||||||
 | 
						SelectSensorsSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensorsByDeviceID.sql
 | 
				
			||||||
 | 
						SelectSensorsByDeviceIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensorsByModel.sql
 | 
				
			||||||
 | 
						SelectSensorsByModelSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensorsByName.sql
 | 
				
			||||||
 | 
						SelectSensorsByNameSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectTemperatureByID.sql
 | 
				
			||||||
 | 
						SelectTemperatureByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectTemperatures.sql
 | 
				
			||||||
 | 
						SelectTemperaturesSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/updateDevice.sql
 | 
				
			||||||
 | 
						UpdateDeviceSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/updateSensor.sql
 | 
				
			||||||
 | 
						UpdateSensorSQL string
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@@ -5,8 +5,6 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.cryptic.systems/volker.raschek/flucky/pkg/repository/postgres"
 | 
					 | 
				
			||||||
	"git.cryptic.systems/volker.raschek/flucky/pkg/repository/sqlite3"
 | 
					 | 
				
			||||||
	"git.cryptic.systems/volker.raschek/flucky/pkg/types"
 | 
						"git.cryptic.systems/volker.raschek/flucky/pkg/types"
 | 
				
			||||||
	"git.cryptic.systems/volker.raschek/go-logger"
 | 
						"git.cryptic.systems/volker.raschek/go-logger"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -33,6 +31,7 @@ type Repository interface {
 | 
				
			|||||||
	GetSensors(ctx context.Context) ([]*types.Sensor, error)
 | 
						GetSensors(ctx context.Context) ([]*types.Sensor, error)
 | 
				
			||||||
	GetTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error)
 | 
						GetTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error)
 | 
				
			||||||
	GetTemperatures(ctx context.Context) ([]*types.MeasuredValue, error)
 | 
						GetTemperatures(ctx context.Context) ([]*types.MeasuredValue, error)
 | 
				
			||||||
 | 
						Import(ctx context.Context, src Repository) error
 | 
				
			||||||
	Migrate(ctx context.Context) error
 | 
						Migrate(ctx context.Context) error
 | 
				
			||||||
	RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error
 | 
						RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error
 | 
				
			||||||
	RemoveDevicesByNames(ctx context.Context, names ...string) error
 | 
						RemoveDevicesByNames(ctx context.Context, names ...string) error
 | 
				
			||||||
@@ -46,7 +45,7 @@ type Repository interface {
 | 
				
			|||||||
func New(databaseURL *url.URL, flogger logger.Logger) (Repository, error) {
 | 
					func New(databaseURL *url.URL, flogger logger.Logger) (Repository, error) {
 | 
				
			||||||
	switch databaseURL.Scheme {
 | 
						switch databaseURL.Scheme {
 | 
				
			||||||
	case "postgres":
 | 
						case "postgres":
 | 
				
			||||||
		repo, err := postgres.New(postgres.Opts{
 | 
							repo, err := NewPostgres(PostgresOpts{
 | 
				
			||||||
			DatabaseURL: databaseURL,
 | 
								DatabaseURL: databaseURL,
 | 
				
			||||||
			Logger:      flogger,
 | 
								Logger:      flogger,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
@@ -63,7 +62,7 @@ func New(databaseURL *url.URL, flogger logger.Logger) (Repository, error) {
 | 
				
			|||||||
		return repo, nil
 | 
							return repo, nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "sqlite3":
 | 
						case "sqlite3":
 | 
				
			||||||
		repo, err := sqlite3.New(sqlite3.Opts{
 | 
							repo, err := NewSQLite(SQLiteOpts{
 | 
				
			||||||
			DatabaseURL: databaseURL,
 | 
								DatabaseURL: databaseURL,
 | 
				
			||||||
			Logger:      flogger,
 | 
								Logger:      flogger,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,8 @@
 | 
				
			|||||||
package sqlite3
 | 
					package repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"database/sql"
 | 
						"database/sql"
 | 
				
			||||||
	"embed"
 | 
					 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
@@ -11,113 +10,20 @@ import (
 | 
				
			|||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.cryptic.systems/volker.raschek/flucky/pkg/repository/postgres"
 | 
				
			||||||
 | 
						"git.cryptic.systems/volker.raschek/flucky/pkg/repository/sqlite3"
 | 
				
			||||||
	"git.cryptic.systems/volker.raschek/flucky/pkg/types"
 | 
						"git.cryptic.systems/volker.raschek/flucky/pkg/types"
 | 
				
			||||||
	"git.cryptic.systems/volker.raschek/go-logger"
 | 
						"git.cryptic.systems/volker.raschek/go-logger"
 | 
				
			||||||
	"github.com/golang-migrate/migrate/v4"
 | 
						"github.com/golang-migrate/migrate/v4"
 | 
				
			||||||
	"github.com/johejo/golang-migrate-extra/source/iofs"
 | 
						"github.com/johejo/golang-migrate-extra/source/iofs"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					type SQLiteOpts struct {
 | 
				
			||||||
	//go:embed ddl/*.sql
 | 
					 | 
				
			||||||
	ddlAssets embed.FS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/deleteDeviceByID.sql
 | 
					 | 
				
			||||||
	deleteDeviceByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/deleteDeviceByName.sql
 | 
					 | 
				
			||||||
	deleteDeviceByNameSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/deleteSensorByID.sql
 | 
					 | 
				
			||||||
	deleteSensorByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/deleteSensorByName.sql
 | 
					 | 
				
			||||||
	deleteSensorByNameSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertDevice.sql
 | 
					 | 
				
			||||||
	insertDeviceSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertHumidity.sql
 | 
					 | 
				
			||||||
	insertHumiditySQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdateDevice.sql
 | 
					 | 
				
			||||||
	insertOrUpdateDeviceSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdateHumidity.sql
 | 
					 | 
				
			||||||
	insertOrUpdateHumiditySQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdatePressure.sql
 | 
					 | 
				
			||||||
	insertOrUpdatePressureSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdateSensor.sql
 | 
					 | 
				
			||||||
	insertOrUpdateSensorSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertOrUpdateTemperature.sql
 | 
					 | 
				
			||||||
	insertOrUpdateTemperatureSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertPressure.sql
 | 
					 | 
				
			||||||
	insertPressureSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertSensor.sql
 | 
					 | 
				
			||||||
	insertSensorSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/insertTemperature.sql
 | 
					 | 
				
			||||||
	insertTemperatureSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectDeviceByID.sql
 | 
					 | 
				
			||||||
	selectDeviceByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectDeviceByName.sql
 | 
					 | 
				
			||||||
	selectDeviceByNameSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectDevices.sql
 | 
					 | 
				
			||||||
	selectDevicesSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectHumidities.sql
 | 
					 | 
				
			||||||
	selectHumiditiesSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectHumidityByID.sql
 | 
					 | 
				
			||||||
	selectHumidityByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectPressureByID.sql
 | 
					 | 
				
			||||||
	selectPressureByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectPressures.sql
 | 
					 | 
				
			||||||
	selectPressuresSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensorByID.sql
 | 
					 | 
				
			||||||
	selectSensorByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensors.sql
 | 
					 | 
				
			||||||
	selectSensorsSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensorsByDeviceID.sql
 | 
					 | 
				
			||||||
	selectSensorsByDeviceIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensorsByModel.sql
 | 
					 | 
				
			||||||
	selectSensorsByModelSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectSensorsByName.sql
 | 
					 | 
				
			||||||
	selectSensorsByNameSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectTemperatureByID.sql
 | 
					 | 
				
			||||||
	selectTemperatureByIDSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/selectTemperatures.sql
 | 
					 | 
				
			||||||
	selectTemperaturesSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/updateDevice.sql
 | 
					 | 
				
			||||||
	updateDeviceSQL string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//go:embed dml/updateSensor.sql
 | 
					 | 
				
			||||||
	updateSensorSQL string
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Opts struct {
 | 
					 | 
				
			||||||
	DatabaseURL *url.URL
 | 
						DatabaseURL *url.URL
 | 
				
			||||||
	Logger      logger.Logger
 | 
						Logger      logger.Logger
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (o *Opts) Validate() error {
 | 
					func (o *SQLiteOpts) Validate() error {
 | 
				
			||||||
	for k, v := range map[string]interface{}{
 | 
						for k, v := range map[string]interface{}{
 | 
				
			||||||
		"DatabaseURL": o.DatabaseURL,
 | 
							"DatabaseURL": o.DatabaseURL,
 | 
				
			||||||
		"Logger":      o.Logger,
 | 
							"Logger":      o.Logger,
 | 
				
			||||||
@@ -134,7 +40,7 @@ func (o *Opts) Validate() error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func New(opts Opts) (*SQLite, error) {
 | 
					func NewSQLite(opts SQLiteOpts) (Repository, error) {
 | 
				
			||||||
	if err := opts.Validate(); err != nil {
 | 
						if err := opts.Validate(); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -175,17 +81,26 @@ type SQLite struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddDevices into the database
 | 
					// AddDevices into the database
 | 
				
			||||||
func (sqlite *SQLite) AddDevices(ctx context.Context, devices ...*types.Device) error {
 | 
					func (d *SQLite) AddDevices(ctx context.Context, devices ...*types.Device) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(insertDeviceSQL)
 | 
						err = d.insertDevices(tx, devices...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *SQLite) insertDevices(tx *sql.Tx, devices ...*types.Device) error {
 | 
				
			||||||
 | 
						stmt, err := tx.Prepare(sqlite3.InsertDeviceSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -198,21 +113,30 @@ func (sqlite *SQLite) AddDevices(ctx context.Context, devices ...*types.Device)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return tx.Commit()
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddOrUpdateDevices into the database
 | 
					// AddOrUpdateDevices into the database
 | 
				
			||||||
func (sqlite *SQLite) AddOrUpdateDevices(ctx context.Context, devices ...*types.Device) error {
 | 
					func (d *SQLite) AddOrUpdateDevices(ctx context.Context, devices ...*types.Device) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(insertOrUpdateDeviceSQL)
 | 
						err = d.insertOrUpdateDevices(tx, devices...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *SQLite) insertOrUpdateDevices(tx *sql.Tx, devices ...*types.Device) error {
 | 
				
			||||||
 | 
						stmt, err := tx.Prepare(sqlite3.InsertOrUpdateDeviceSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -225,13 +149,13 @@ func (sqlite *SQLite) AddOrUpdateDevices(ctx context.Context, devices ...*types.
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return tx.Commit()
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddMeasuredValues into the database
 | 
					// AddMeasuredValues into the database
 | 
				
			||||||
func (sqlite *SQLite) AddMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error {
 | 
					func (d *SQLite) AddMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0)
 | 
						splittedMeasuredValues := make(map[types.MeasuredValueType][]*types.MeasuredValue, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -242,53 +166,27 @@ func (sqlite *SQLite) AddMeasuredValues(ctx context.Context, measuredValues ...*
 | 
				
			|||||||
		splittedMeasuredValues[measuredValue.ValueType] = append(splittedMeasuredValues[measuredValue.ValueType], measuredValue)
 | 
							splittedMeasuredValues[measuredValue.ValueType] = append(splittedMeasuredValues[measuredValue.ValueType], measuredValue)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// General insert function
 | 
					 | 
				
			||||||
	insert := func(tx *sql.Tx, query string, measuredValues []*types.MeasuredValue) error {
 | 
					 | 
				
			||||||
		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 {
 | 
						for measuredValueType, measuredValues := range splittedMeasuredValues {
 | 
				
			||||||
		var query string
 | 
							var query string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch measuredValueType {
 | 
							switch measuredValueType {
 | 
				
			||||||
		case types.Humidity:
 | 
							case types.Humidity:
 | 
				
			||||||
			query = insertHumiditySQL
 | 
								query = sqlite3.InsertHumiditySQL
 | 
				
			||||||
		case types.Pressure:
 | 
							case types.Pressure:
 | 
				
			||||||
			query = insertPressureSQL
 | 
								query = sqlite3.InsertPressureSQL
 | 
				
			||||||
		case types.Temperature:
 | 
							case types.Temperature:
 | 
				
			||||||
			query = insertTemperatureSQL
 | 
								query = sqlite3.InsertTemperatureSQL
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return fmt.Errorf("Measured value type %v not supported", measuredValueType)
 | 
								return fmt.Errorf("Measured value type %v not supported", measuredValueType)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err := insert(tx, query, measuredValues)
 | 
							err := d.insertMeasuredValues(tx, query, measuredValues...)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -297,29 +195,7 @@ func (sqlite *SQLite) AddMeasuredValues(ctx context.Context, measuredValues ...*
 | 
				
			|||||||
	return tx.Commit()
 | 
						return tx.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddOrUpdateMeasuredValues into the database
 | 
					func (d *SQLite) insertMeasuredValues(tx *sql.Tx, query string, measuredValues ...*types.MeasuredValue) error {
 | 
				
			||||||
func (sqlite *SQLite) AddOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error {
 | 
					 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
					 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer tx.Rollback()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// General insert function
 | 
					 | 
				
			||||||
	insert := func(tx *sql.Tx, query string, measuredValues []*types.MeasuredValue) error {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
@@ -344,21 +220,41 @@ func (sqlite *SQLite) AddOrUpdateMeasuredValues(ctx context.Context, measuredVal
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AddOrUpdateMeasuredValues into the database
 | 
				
			||||||
 | 
					func (d *SQLite) AddOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error {
 | 
				
			||||||
 | 
						d.mutex.Lock()
 | 
				
			||||||
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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 := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for measuredValueType, measuredValues := range splittedMeasuredValues {
 | 
						for measuredValueType, measuredValues := range splittedMeasuredValues {
 | 
				
			||||||
		var queryFile string
 | 
							var query string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch measuredValueType {
 | 
							switch measuredValueType {
 | 
				
			||||||
		case types.Humidity:
 | 
							case types.Humidity:
 | 
				
			||||||
			queryFile = insertOrUpdateHumiditySQL
 | 
								query = sqlite3.InsertOrUpdateHumiditySQL
 | 
				
			||||||
		case types.Pressure:
 | 
							case types.Pressure:
 | 
				
			||||||
			queryFile = insertOrUpdatePressureSQL
 | 
								query = sqlite3.InsertOrUpdatePressureSQL
 | 
				
			||||||
		case types.Temperature:
 | 
							case types.Temperature:
 | 
				
			||||||
			queryFile = insertOrUpdateTemperatureSQL
 | 
								query = sqlite3.InsertOrUpdateTemperatureSQL
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return fmt.Errorf("Measured value type %v not supported", measuredValueType)
 | 
								return fmt.Errorf("Measured value type %v not supported", measuredValueType)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err := insert(tx, queryFile, measuredValues)
 | 
							err := d.insertOrUpdateMeasuredValues(tx, query, measuredValues...)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -367,18 +263,43 @@ func (sqlite *SQLite) AddOrUpdateMeasuredValues(ctx context.Context, measuredVal
 | 
				
			|||||||
	return tx.Commit()
 | 
						return tx.Commit()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddSensors into the database
 | 
					func (d *SQLite) insertOrUpdateMeasuredValues(tx *sql.Tx, query string, measuredValues ...*types.MeasuredValue) error {
 | 
				
			||||||
func (sqlite *SQLite) AddSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						if err != nil {
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer stmt.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AddSensors into the database
 | 
				
			||||||
 | 
					func (d *SQLite) AddSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
				
			||||||
 | 
						d.mutex.Lock()
 | 
				
			||||||
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(insertSensorSQL)
 | 
						stmt, err := tx.Prepare(sqlite3.InsertSensorSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -409,17 +330,26 @@ func (sqlite *SQLite) AddSensors(ctx context.Context, sensors ...*types.Sensor)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddOrUpdateSensors into the database
 | 
					// AddOrUpdateSensors into the database
 | 
				
			||||||
func (sqlite *SQLite) AddOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
					func (d *SQLite) AddOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(insertOrUpdateSensorSQL)
 | 
						err = d.insertOrUpdateSensors(tx, sensors...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *SQLite) insertOrUpdateSensors(tx *sql.Tx, sensors ...*types.Sensor) error {
 | 
				
			||||||
 | 
						stmt, err := tx.Prepare(sqlite3.InsertOrUpdateSensorSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -446,28 +376,28 @@ func (sqlite *SQLite) AddOrUpdateSensors(ctx context.Context, sensors ...*types.
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return tx.Commit()
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Close closes the database and prevents new queries from starting. Close then
 | 
					// 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.
 | 
					// waits for all queries that have started processing on the server to finish.
 | 
				
			||||||
func (sqlite *SQLite) Close() error {
 | 
					func (d *SQLite) Close() error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
	return sqlite.dbo.Close()
 | 
						return d.dbo.Close()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Migrate creates all required tables if not exist
 | 
					// Migrate creates all required tables if not exist
 | 
				
			||||||
func (sqlite *SQLite) Migrate(ctx context.Context) error {
 | 
					func (d *SQLite) Migrate(ctx context.Context) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sourceDriver, err := iofs.New(ddlAssets, "ddl")
 | 
						sourceDriver, err := iofs.New(sqlite3.DDLAssets, sqlite3.DDLAssetPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m, err := migrate.NewWithSourceInstance("iofs", sourceDriver, sqlite.databaseURL.String())
 | 
						m, err := migrate.NewWithSourceInstance("iofs", sourceDriver, d.databaseURL.String())
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -482,17 +412,17 @@ func (sqlite *SQLite) Migrate(ctx context.Context) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDevice from database
 | 
					// GetDevice from database
 | 
				
			||||||
func (sqlite *SQLite) GetDeviceByID(ctx context.Context, id string) (*types.Device, error) {
 | 
					func (d *SQLite) GetDeviceByID(ctx context.Context, id string) (*types.Device, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	devices, err := sqlite.selectDevices(tx, selectDeviceByIDSQL, id)
 | 
						devices, err := d.selectDevices(tx, sqlite3.SelectDeviceByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -510,17 +440,17 @@ func (sqlite *SQLite) GetDeviceByID(ctx context.Context, id string) (*types.Devi
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDevice from database
 | 
					// GetDevice from database
 | 
				
			||||||
func (sqlite *SQLite) GetDeviceByName(ctx context.Context, name string) (*types.Device, error) {
 | 
					func (d *SQLite) GetDeviceByName(ctx context.Context, name string) (*types.Device, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	devices, err := sqlite.selectDevices(tx, selectDeviceByNameSQL, name)
 | 
						devices, err := d.selectDevices(tx, sqlite3.SelectDeviceByNameSQL, name)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -538,17 +468,17 @@ func (sqlite *SQLite) GetDeviceByName(ctx context.Context, name string) (*types.
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDevices from the database
 | 
					// GetDevices from the database
 | 
				
			||||||
func (sqlite *SQLite) GetDevices(ctx context.Context) ([]*types.Device, error) {
 | 
					func (d *SQLite) GetDevices(ctx context.Context) ([]*types.Device, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	devices, err := sqlite.selectDevices(tx, selectDevicesSQL)
 | 
						devices, err := d.selectDevices(tx, sqlite3.SelectDevicesSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -561,7 +491,7 @@ func (sqlite *SQLite) GetDevices(ctx context.Context) ([]*types.Device, error) {
 | 
				
			|||||||
	return devices, nil
 | 
						return devices, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (sqlite *SQLite) selectDevices(tx *sql.Tx, query string, args ...interface{}) ([]*types.Device, error) {
 | 
					func (d *SQLite) selectDevices(tx *sql.Tx, query string, args ...interface{}) ([]*types.Device, error) {
 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return nil, fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
@@ -594,17 +524,17 @@ func (sqlite *SQLite) selectDevices(tx *sql.Tx, query string, args ...interface{
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHumidity returns humidity from the database
 | 
					// GetHumidity returns humidity from the database
 | 
				
			||||||
func (sqlite *SQLite) GetHumidityByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
					func (d *SQLite) GetHumidityByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := sqlite.selectMeasuredValue(tx, selectHumidityByIDSQL, id)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, sqlite3.SelectHumidityByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -626,17 +556,17 @@ func (sqlite *SQLite) GetHumidityByID(ctx context.Context, id string) (*types.Me
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetHumidities returns humidities from the database
 | 
					// GetHumidities returns humidities from the database
 | 
				
			||||||
func (sqlite *SQLite) GetHumidities(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
					func (d *SQLite) GetHumidities(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := sqlite.selectMeasuredValue(tx, selectHumiditiesSQL)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, sqlite3.SelectHumiditiesSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -653,7 +583,7 @@ func (sqlite *SQLite) GetHumidities(ctx context.Context) ([]*types.MeasuredValue
 | 
				
			|||||||
	return measuredValues, nil
 | 
						return measuredValues, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (sqlite *SQLite) selectMeasuredValue(tx *sql.Tx, query string, args ...interface{}) ([]*types.MeasuredValue, error) {
 | 
					func (d *SQLite) selectMeasuredValue(tx *sql.Tx, query string, args ...interface{}) ([]*types.MeasuredValue, error) {
 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -689,17 +619,17 @@ func (sqlite *SQLite) selectMeasuredValue(tx *sql.Tx, query string, args ...inte
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetPressure returns pressure from the database
 | 
					// GetPressure returns pressure from the database
 | 
				
			||||||
func (sqlite *SQLite) GetPressureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
					func (d *SQLite) GetPressureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := sqlite.selectMeasuredValue(tx, selectPressureByIDSQL, id)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, sqlite3.SelectPressureByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -721,17 +651,17 @@ func (sqlite *SQLite) GetPressureByID(ctx context.Context, id string) (*types.Me
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetPressures returns pressure from the database
 | 
					// GetPressures returns pressure from the database
 | 
				
			||||||
func (sqlite *SQLite) GetPressures(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
					func (d *SQLite) GetPressures(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := sqlite.selectMeasuredValue(tx, selectPressuresSQL)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, sqlite3.SelectPressuresSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -749,17 +679,17 @@ func (sqlite *SQLite) GetPressures(ctx context.Context) ([]*types.MeasuredValue,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensor from database
 | 
					// GetSensor from database
 | 
				
			||||||
func (sqlite *SQLite) GetSensorByID(ctx context.Context, id string) (*types.Sensor, error) {
 | 
					func (d *SQLite) GetSensorByID(ctx context.Context, id string) (*types.Sensor, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sensors, err := sqlite.selectSensors(tx, selectSensorByIDSQL, id)
 | 
						sensors, err := d.selectSensors(tx, sqlite3.SelectSensorByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -777,17 +707,17 @@ func (sqlite *SQLite) GetSensorByID(ctx context.Context, id string) (*types.Sens
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensors from the database
 | 
					// GetSensors from the database
 | 
				
			||||||
func (sqlite *SQLite) GetSensors(ctx context.Context) ([]*types.Sensor, error) {
 | 
					func (d *SQLite) GetSensors(ctx context.Context) ([]*types.Sensor, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sensors, err := sqlite.selectSensors(tx, selectSensorsSQL)
 | 
						sensors, err := d.selectSensors(tx, sqlite3.SelectSensorsSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -801,11 +731,11 @@ func (sqlite *SQLite) GetSensors(ctx context.Context) ([]*types.Sensor, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensorsByModels from the database
 | 
					// GetSensorsByModels from the database
 | 
				
			||||||
func (sqlite *SQLite) GetSensorsByDeviceIDs(ctx context.Context, deviceIDs ...string) ([]*types.Sensor, error) {
 | 
					func (d *SQLite) GetSensorsByDeviceIDs(ctx context.Context, deviceIDs ...string) ([]*types.Sensor, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -813,7 +743,7 @@ func (sqlite *SQLite) GetSensorsByDeviceIDs(ctx context.Context, deviceIDs ...st
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cachedSensors := make([]*types.Sensor, 0)
 | 
						cachedSensors := make([]*types.Sensor, 0)
 | 
				
			||||||
	for i := range deviceIDs {
 | 
						for i := range deviceIDs {
 | 
				
			||||||
		sensors, err := sqlite.selectSensors(tx, selectSensorsByDeviceIDSQL, deviceIDs[i])
 | 
							sensors, err := d.selectSensors(tx, sqlite3.SelectSensorsByDeviceIDSQL, deviceIDs[i])
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -830,11 +760,11 @@ func (sqlite *SQLite) GetSensorsByDeviceIDs(ctx context.Context, deviceIDs ...st
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensorsByModels from the database
 | 
					// GetSensorsByModels from the database
 | 
				
			||||||
func (sqlite *SQLite) GetSensorsByModels(ctx context.Context, sensorModels ...string) ([]*types.Sensor, error) {
 | 
					func (d *SQLite) GetSensorsByModels(ctx context.Context, sensorModels ...string) ([]*types.Sensor, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -842,7 +772,7 @@ func (sqlite *SQLite) GetSensorsByModels(ctx context.Context, sensorModels ...st
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cachedSensors := make([]*types.Sensor, 0)
 | 
						cachedSensors := make([]*types.Sensor, 0)
 | 
				
			||||||
	for i := range sensorModels {
 | 
						for i := range sensorModels {
 | 
				
			||||||
		sensors, err := sqlite.selectSensors(tx, selectSensorsByModelSQL, sensorModels[i])
 | 
							sensors, err := d.selectSensors(tx, sqlite3.SelectSensorsByModelSQL, sensorModels[i])
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -859,11 +789,11 @@ func (sqlite *SQLite) GetSensorsByModels(ctx context.Context, sensorModels ...st
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSensorsByModels from the database
 | 
					// GetSensorsByModels from the database
 | 
				
			||||||
func (sqlite *SQLite) GetSensorsByNames(ctx context.Context, sensorNames ...string) ([]*types.Sensor, error) {
 | 
					func (d *SQLite) GetSensorsByNames(ctx context.Context, sensorNames ...string) ([]*types.Sensor, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -871,7 +801,7 @@ func (sqlite *SQLite) GetSensorsByNames(ctx context.Context, sensorNames ...stri
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cachedSensors := make([]*types.Sensor, 0)
 | 
						cachedSensors := make([]*types.Sensor, 0)
 | 
				
			||||||
	for i := range sensorNames {
 | 
						for i := range sensorNames {
 | 
				
			||||||
		sensors, err := sqlite.selectSensors(tx, selectSensorsByNameSQL, sensorNames[i])
 | 
							sensors, err := d.selectSensors(tx, sqlite3.SelectSensorsByNameSQL, sensorNames[i])
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -887,7 +817,7 @@ func (sqlite *SQLite) GetSensorsByNames(ctx context.Context, sensorNames ...stri
 | 
				
			|||||||
	return cachedSensors, nil
 | 
						return cachedSensors, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (sqlite *SQLite) selectSensors(tx *sql.Tx, query string, args ...interface{}) ([]*types.Sensor, error) {
 | 
					func (d *SQLite) selectSensors(tx *sql.Tx, query string, args ...interface{}) ([]*types.Sensor, error) {
 | 
				
			||||||
	stmt, err := tx.Prepare(query)
 | 
						stmt, err := tx.Prepare(query)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return nil, fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
@@ -929,17 +859,17 @@ func (sqlite *SQLite) selectSensors(tx *sql.Tx, query string, args ...interface{
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetTemperature returns temperatures from the database
 | 
					// GetTemperature returns temperatures from the database
 | 
				
			||||||
func (sqlite *SQLite) GetTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
					func (d *SQLite) GetTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := sqlite.selectMeasuredValue(tx, selectTemperatureByIDSQL, id)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, sqlite3.SelectTemperatureByIDSQL, id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -961,17 +891,17 @@ func (sqlite *SQLite) GetTemperatureByID(ctx context.Context, id string) (*types
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetTemperatures returns temperatures from the database
 | 
					// GetTemperatures returns temperatures from the database
 | 
				
			||||||
func (sqlite *SQLite) GetTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
					func (d *SQLite) GetTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	measuredValues, err := sqlite.selectMeasuredValue(tx, selectTemperaturesSQL)
 | 
						measuredValues, err := d.selectMeasuredValue(tx, sqlite3.SelectTemperaturesSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -988,18 +918,65 @@ func (sqlite *SQLite) GetTemperatures(ctx context.Context) ([]*types.MeasuredVal
 | 
				
			|||||||
	return measuredValues, nil
 | 
						return measuredValues, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveDevices from the database
 | 
					// Import imports devices, sensors and all measured values from a source
 | 
				
			||||||
func (sqlite *SQLite) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error {
 | 
					// repository. Existing entries will be updated.
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
					func (d *SQLite) Import(ctx context.Context, src Repository) error {
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						devices, err := src.GetDevices(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = d.insertOrUpdateDevices(tx, devices...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sensors, err := src.GetSensors(ctx)
 | 
				
			||||||
 | 
						err = d.insertOrUpdateSensors(tx, sensors...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, value := range []struct {
 | 
				
			||||||
 | 
							f     func(ctx context.Context) ([]*types.MeasuredValue, error)
 | 
				
			||||||
 | 
							query string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{f: src.GetHumidities, query: postgres.InsertOrUpdateHumiditySQL},
 | 
				
			||||||
 | 
							{f: src.GetPressures, query: postgres.InsertOrUpdatePressureSQL},
 | 
				
			||||||
 | 
							{f: src.GetTemperatures, query: postgres.InsertOrUpdateTemperatureSQL},
 | 
				
			||||||
 | 
						} {
 | 
				
			||||||
 | 
							measuredValues, err := value.f(ctx)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = d.insertOrUpdateMeasuredValues(tx, value.query, measuredValues...)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tx.Commit()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RemoveDevices from the database
 | 
				
			||||||
 | 
					func (d *SQLite) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...string) error {
 | 
				
			||||||
 | 
						d.mutex.Lock()
 | 
				
			||||||
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(deleteDeviceByIDSQL)
 | 
						stmt, err := tx.Prepare(sqlite3.DeleteDeviceByIDSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1016,17 +993,17 @@ func (sqlite *SQLite) RemoveDevicesByIDs(ctx context.Context, deviceIDs ...strin
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveDevices from the database
 | 
					// RemoveDevices from the database
 | 
				
			||||||
func (sqlite *SQLite) RemoveDevicesByNames(ctx context.Context, names ...string) error {
 | 
					func (d *SQLite) RemoveDevicesByNames(ctx context.Context, names ...string) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(deleteDeviceByNameSQL)
 | 
						stmt, err := tx.Prepare(sqlite3.DeleteDeviceByNameSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1043,17 +1020,17 @@ func (sqlite *SQLite) RemoveDevicesByNames(ctx context.Context, names ...string)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveSensors from the database
 | 
					// RemoveSensors from the database
 | 
				
			||||||
func (sqlite *SQLite) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...string) error {
 | 
					func (d *SQLite) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...string) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(deleteSensorByIDSQL)
 | 
						stmt, err := tx.Prepare(sqlite3.DeleteSensorByIDSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1070,17 +1047,17 @@ func (sqlite *SQLite) RemoveSensorsByIDs(ctx context.Context, sensorIDs ...strin
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveSensors from the database
 | 
					// RemoveSensors from the database
 | 
				
			||||||
func (sqlite *SQLite) RemoveSensorsByNames(ctx context.Context, names ...string) error {
 | 
					func (d *SQLite) RemoveSensorsByNames(ctx context.Context, names ...string) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
							return fmt.Errorf("Failed to begin new transaction: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(deleteSensorByNameSQL)
 | 
						stmt, err := tx.Prepare(sqlite3.DeleteSensorByNameSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
							return fmt.Errorf("Failed to prepare statement: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1097,17 +1074,17 @@ func (sqlite *SQLite) RemoveSensorsByNames(ctx context.Context, names ...string)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateDevices updates a device in the database
 | 
					// UpdateDevices updates a device in the database
 | 
				
			||||||
func (sqlite *SQLite) UpdateDevices(ctx context.Context, devices ...*types.Device) error {
 | 
					func (d *SQLite) UpdateDevices(ctx context.Context, devices ...*types.Device) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(updateDeviceSQL)
 | 
						stmt, err := tx.Prepare(sqlite3.UpdateDeviceSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1130,17 +1107,17 @@ func (sqlite *SQLite) UpdateDevices(ctx context.Context, devices ...*types.Devic
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateSensors updates a sensor in the database
 | 
					// UpdateSensors updates a sensor in the database
 | 
				
			||||||
func (sqlite *SQLite) UpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
					func (d *SQLite) UpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
 | 
				
			||||||
	sqlite.mutex.Lock()
 | 
						d.mutex.Lock()
 | 
				
			||||||
	defer sqlite.mutex.Unlock()
 | 
						defer d.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tx, err := sqlite.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
						tx, err := d.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer tx.Rollback()
 | 
						defer tx.Rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stmt, err := tx.Prepare(updateSensorSQL)
 | 
						stmt, err := tx.Prepare(sqlite3.UpdateSensorSQL)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
							
								
								
									
										100
									
								
								pkg/repository/sqlite3/statements.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								pkg/repository/sqlite3/statements.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					package sqlite3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "embed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						DDLAssetPath = "ddl"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed ddl/*.sql
 | 
				
			||||||
 | 
						DDLAssets embed.FS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/deleteDeviceByID.sql
 | 
				
			||||||
 | 
						DeleteDeviceByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/deleteDeviceByName.sql
 | 
				
			||||||
 | 
						DeleteDeviceByNameSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/deleteSensorByID.sql
 | 
				
			||||||
 | 
						DeleteSensorByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/deleteSensorByName.sql
 | 
				
			||||||
 | 
						DeleteSensorByNameSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertDevice.sql
 | 
				
			||||||
 | 
						InsertDeviceSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertHumidity.sql
 | 
				
			||||||
 | 
						InsertHumiditySQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdateDevice.sql
 | 
				
			||||||
 | 
						InsertOrUpdateDeviceSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdateHumidity.sql
 | 
				
			||||||
 | 
						InsertOrUpdateHumiditySQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdatePressure.sql
 | 
				
			||||||
 | 
						InsertOrUpdatePressureSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdateSensor.sql
 | 
				
			||||||
 | 
						InsertOrUpdateSensorSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertOrUpdateTemperature.sql
 | 
				
			||||||
 | 
						InsertOrUpdateTemperatureSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertPressure.sql
 | 
				
			||||||
 | 
						InsertPressureSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertSensor.sql
 | 
				
			||||||
 | 
						InsertSensorSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/insertTemperature.sql
 | 
				
			||||||
 | 
						InsertTemperatureSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectDeviceByID.sql
 | 
				
			||||||
 | 
						SelectDeviceByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectDeviceByName.sql
 | 
				
			||||||
 | 
						SelectDeviceByNameSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectDevices.sql
 | 
				
			||||||
 | 
						SelectDevicesSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectHumidities.sql
 | 
				
			||||||
 | 
						SelectHumiditiesSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectHumidityByID.sql
 | 
				
			||||||
 | 
						SelectHumidityByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectPressureByID.sql
 | 
				
			||||||
 | 
						SelectPressureByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectPressures.sql
 | 
				
			||||||
 | 
						SelectPressuresSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensorByID.sql
 | 
				
			||||||
 | 
						SelectSensorByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensors.sql
 | 
				
			||||||
 | 
						SelectSensorsSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensorsByDeviceID.sql
 | 
				
			||||||
 | 
						SelectSensorsByDeviceIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensorsByModel.sql
 | 
				
			||||||
 | 
						SelectSensorsByModelSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectSensorsByName.sql
 | 
				
			||||||
 | 
						SelectSensorsByNameSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectTemperatureByID.sql
 | 
				
			||||||
 | 
						SelectTemperatureByIDSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/selectTemperatures.sql
 | 
				
			||||||
 | 
						SelectTemperaturesSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/updateDevice.sql
 | 
				
			||||||
 | 
						UpdateDeviceSQL string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//go:embed dml/updateSensor.sql
 | 
				
			||||||
 | 
						UpdateSensorSQL string
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user