PKGBUILD/pkg/repository/db/db.go

135 lines
4.1 KiB
Go
Raw Normal View History

2020-05-21 15:40:24 +00:00
package db
import (
"context"
"database/sql"
"fmt"
"net/url"
"os"
"path/filepath"
postgresdml "git.cryptic.systems/volker.raschek/flucky/pkg/repository/db/postgres/dml"
sqlite3dml "git.cryptic.systems/volker.raschek/flucky/pkg/repository/db/sqlite3/dml"
2020-06-10 19:13:05 +00:00
"git.cryptic.systems/volker.raschek/flucky/pkg/types"
"git.cryptic.systems/volker.raschek/go-logger"
2020-05-21 15:40:24 +00:00
)
// Database is a general interface for a database backend like postgres, oracle
// or sqlite
2020-05-21 15:40:24 +00:00
type Database interface {
Close() error
2020-05-21 15:40:24 +00:00
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
2020-05-21 15:40:24 +00:00
InsertMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error
InsertOrUpdateMeasuredValues(ctx context.Context, measuredValues ...*types.MeasuredValue) error
2020-05-21 15:40:24 +00:00
InsertSensors(ctx context.Context, sensors ...*types.Sensor) error
InsertOrUpdateSensors(ctx context.Context, sensors ...*types.Sensor) error
Migrate(ctx context.Context) error
2020-05-21 15:40:24 +00:00
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(databaseURL *url.URL, flogger logger.Logger) (Database, error) {
2020-05-21 15:40:24 +00:00
// Check of nil pointer
for _, parameter := range []interface{}{
databaseURL,
2020-05-21 15:40:24 +00:00
flogger,
} {
if parameter == nil {
return nil, fmt.Errorf("Parameter does not be nil")
}
}
var (
database Database
err error
)
switch databaseURL.Scheme {
case "postgres":
// postgres://[user]:[password]@[host]:[port]/[path]?[query]
newDBO, err := sql.Open(databaseURL.Scheme, databaseURL.String())
if err != nil {
return nil, err
}
queries := make(map[string]string, 0)
for _, assetName := range postgresdml.AssetNames() {
body, err := postgresdml.Asset(assetName)
if err != nil {
return nil, fmt.Errorf("Failed to load asset %v, %w", assetName, err)
}
queries[assetName] = string(body)
}
database = &Postgres{
databaseURL: databaseURL,
dbo: newDBO,
flogger: flogger,
queries: queries,
}
2020-05-21 15:40:24 +00:00
case "sqlite3":
// Create directory if not exist
if _, err := os.Stat(filepath.Dir(databaseURL.Path)); os.IsNotExist(err) {
err := os.MkdirAll(filepath.Dir(databaseURL.Path), 0755)
2020-05-21 15:40:24 +00:00
if err != nil {
return nil, err
}
}
// enable foreign keys
values := databaseURL.Query()
values.Set("_foreign_keys", "on")
customRawURL := fmt.Sprintf("file://%v?%v", databaseURL.Path, values.Encode())
sqlDB, err := sql.Open("sqlite3", customRawURL)
2020-05-21 15:40:24 +00:00
if err != nil {
return nil, err
}
queries := make(map[string]string, 0)
for _, assetName := range sqlite3dml.AssetNames() {
body, err := sqlite3dml.Asset(assetName)
if err != nil {
return nil, fmt.Errorf("Failed to load asset %v, %w", assetName, err)
}
queries[assetName] = string(body)
}
2020-05-21 15:40:24 +00:00
database = &SQLite{
databaseURL: databaseURL,
dbo: sqlDB,
flogger: flogger,
queries: queries,
2020-05-21 15:40:24 +00:00
}
default:
return nil, fmt.Errorf("Unsupported database scheme: %v", databaseURL.Scheme)
2020-05-21 15:40:24 +00:00
}
2020-05-21 18:07:32 +00:00
// Initialize database scheme if not exists
err = database.Migrate(context.Background())
2020-05-21 15:40:24 +00:00
if err != nil {
return nil, err
}
return database, nil
}