PKGBUILD/pkg/repository/db/db.go
markus 522fe2746a
fix: add or update devices, sensors and measured values
Add additional functions to the repository to add or update devices,
sensors or measured values. Furthermore the test has been adapt to the
new functions.
2020-12-14 20:54:20 +01:00

128 lines
3.5 KiB
Go

package db
import (
"context"
"database/sql"
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
"git.cryptic.systems/volker.raschek/flucky/pkg/types"
"git.cryptic.systems/volker.raschek/go-logger"
)
// Database is a general interface for a database backend like postgres, oracle
// or sqlite
type Database interface {
Close() error
DeleteDevices(ctx context.Context, deviceIDs ...string) error
DeleteSensors(ctx context.Context, sensorIDs ...string) error
InsertDevices(ctx context.Context, devices ...*types.Device) error
InsertOrUpdateDevices(ctx context.Context, devices ...*types.Device) error
InsertMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error
InsertOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error
InsertSensors(ctx context.Context, sensors ...*types.Sensor) error
InsertOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error
Scheme(ctx context.Context) error
SelectDevice(ctx context.Context, deviceID string) (*types.Device, error)
SelectDevices(ctx context.Context) ([]*types.Device, error)
SelectHumidity(ctx context.Context, id string) (*types.MeasuredValue, error)
SelectHumidities(ctx context.Context) ([]*types.MeasuredValue, error)
SelectPressure(ctx context.Context, id string) (*types.MeasuredValue, error)
SelectPressures(ctx context.Context) ([]*types.MeasuredValue, error)
SelectSensor(ctx context.Context, sensorID string) (*types.Sensor, error)
SelectSensors(ctx context.Context) ([]*types.Sensor, error)
SelectTemperature(ctx context.Context, id string) (*types.MeasuredValue, error)
SelectTemperatures(ctx context.Context) ([]*types.MeasuredValue, error)
UpdateDevices(ctx context.Context, devices ...*types.Device) error
UpdateSensors(ctx context.Context, sensors ...*types.Sensor) error
}
// New returns a new database backend interface
func New(dsnURL *url.URL, flogger logger.Logger) (Database, error) {
// Check of nil pointer
for _, parameter := range []interface{}{
dsnURL,
flogger,
} {
if parameter == nil {
return nil, fmt.Errorf("Parameter does not be nil")
}
}
// Load Queryfiles
queries := make(map[string]string, 0)
for _, asset := range AssetNames() {
if !strings.Contains(asset, dsnURL.Scheme) {
continue
}
body, err := Asset(asset)
if err != nil {
return nil, err
}
queryFile := filepath.Base(asset)
queries[queryFile] = string(body)
}
var (
database Database
err error
)
switch dsnURL.Scheme {
case "postgres":
// postgres://[user]:[password]@[host]:[port]/[path]?[query]
newDBO, err := sql.Open(dsnURL.Scheme, dsnURL.String())
if err != nil {
return nil, err
}
database = &Postgres{
dbo: newDBO,
flogger: flogger,
queries: queries,
}
case "sqlite3":
// Create directory where the db file will be created if not exists.
if _, err := os.Stat(filepath.Dir(dsnURL.Path)); os.IsNotExist(err) {
err := os.MkdirAll(filepath.Dir(dsnURL.Path), 0755)
if err != nil {
return nil, err
}
}
// sqlite3:///[path]?[query] flucky dsn
// file:///[path]?[query] sql-lib dsn
newDBO, err := sql.Open(dsnURL.Scheme, fmt.Sprintf("file://%v?%v", dsnURL.Path, dsnURL.RawQuery))
if err != nil {
return nil, err
}
database = &SQLite{
dbo: newDBO,
flogger: flogger,
queries: queries,
}
default:
return nil, fmt.Errorf("Unsupported database scheme: %v", dsnURL.Scheme)
}
// Initialize database scheme if not exists
err = database.Scheme(context.Background())
if err != nil {
return nil, err
}
return database, nil
}