fix(pkg/daemon): save measured values into postgres database if defined
This commit is contained in:
60 files changed
+670
-368
No files matched your search
+2
-2
@@ -7,11 +7,11 @@ jobs:
|
||||
include:
|
||||
- stage: build
|
||||
name: go-build
|
||||
script: make container/all
|
||||
script: make container-run/all
|
||||
|
||||
deploy:
|
||||
- provider: script
|
||||
script: make container/release
|
||||
script: make container-run/release/all
|
||||
# skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM busybox:latest
|
||||
COPY bin/linux/amd64/flucky /usr/bin/flucky
|
||||
ENTRYPOINT [ "/usr/bin/flucky" ]
|
||||
@@ -5,90 +5,185 @@
|
||||
UID?=$(shell id --user)
|
||||
GID?=$(shell id --group)
|
||||
|
||||
# VERSION
|
||||
IMAGE_VERSION:=$(or ${VERSION}, latest)
|
||||
|
||||
# VERSION/RELEASE
|
||||
# If no version is specified as a parameter of make, the last git hash
|
||||
# value is taken.
|
||||
VERSION:=$(or ${TRAVIS_TAG}, $(shell git rev-parse --short HEAD)-git)
|
||||
VERSION?=$(shell git describe --abbrev=0)+hash.$(shell git rev-parse --short HEAD)
|
||||
RELEASE?=1
|
||||
|
||||
|
||||
# CONTAINER_RUNTIME
|
||||
CONTAINER_RUNTIME?=$(shell which docker)
|
||||
|
||||
# BUILD_IMAGE
|
||||
BUILD_IMAGE:=volkerraschek/build-image:latest
|
||||
|
||||
# GH_USER/GITHUB_TOKEN
|
||||
# It's the user name from github.com and his token. This token and the username
|
||||
# can be set over encrypted environment variables in the ci/cd pipeline
|
||||
GITHUB_USER=volker-raschek
|
||||
GITHUB_TOKEN?=""
|
||||
|
||||
# BUILD_IMAGE
|
||||
BUILD_IMAGE:=volkerraschek/build-image:latest
|
||||
|
||||
# EXECUTABLE
|
||||
# Executable binary which should be compiled for different architecures
|
||||
EXECUTABLE:=flucky
|
||||
|
||||
# UNIX_EXECUTABLES
|
||||
# DARWIN_EXECUTABLES AND TARGETS
|
||||
DARWIN_EXECUTABLES:=\
|
||||
darwin/386/${EXECUTABLE} \
|
||||
darwin/amd64/${EXECUTABLE}
|
||||
|
||||
DARWIN_EXECUTABLE_TARGETS:=${DARWIN_EXECUTABLES:%=bin/%}
|
||||
|
||||
# FREEBSD_EXECUTABLES AND TARGETS
|
||||
FREEBSD_EXECUTABLES:= \
|
||||
freebsd/amd64/${EXECUTABLE}
|
||||
|
||||
FREEBSD_EXECUTABLE_TARGETS:=${FREEBSD_EXECUTABLES:%=bin/%}
|
||||
|
||||
# LINUX_EXECUTABLES AND TARGETS
|
||||
LINUX_EXECUTABLES:= \
|
||||
linux/amd64/${EXECUTABLE} \
|
||||
linux/386/${EXECUTABLE} \
|
||||
linux/arm/5/${EXECUTABLE} \
|
||||
linux/arm/7/${EXECUTABLE}
|
||||
|
||||
LINUX_EXECUTABLE_TARGETS:=${LINUX_EXECUTABLES:%=bin/%}
|
||||
|
||||
# UNIX_EXECUTABLES AND TARGETS
|
||||
# Define all executables for different architectures and operation systems
|
||||
UNIX_EXECUTABLES:= \
|
||||
darwin/386/$(EXECUTABLE) \
|
||||
darwin/amd64/$(EXECUTABLE) \
|
||||
freebsd/amd64/$(EXECUTABLE) \
|
||||
linux/386/$(EXECUTABLE) \
|
||||
linux/amd64/$(EXECUTABLE) \
|
||||
linux/arm/5/$(EXECUTABLE) \
|
||||
linux/arm/7/$(EXECUTABLE) \
|
||||
${DARWIN_EXECUTABLES} \
|
||||
${FREEBSD_EXECUTABLES} \
|
||||
${LINUX_EXECUTABLES}
|
||||
|
||||
UNIX_EXECUTABLE_TARGETS:= \
|
||||
${DARWIN_EXECUTABLE_TARGETS} \
|
||||
${FREEBSD_EXECUTABLE_TARGETS} \
|
||||
${LINUX_EXECUTABLE_TARGETS}
|
||||
|
||||
# EXECUTABLE_TARGETS
|
||||
# Include the relative paths to all executables
|
||||
EXECUTABLE_TARGETS=$(UNIX_EXECUTABLES:%=bin/%)
|
||||
# Include all UNIX and Windows targets.
|
||||
EXECUTABLE_TARGETS:= \
|
||||
${UNIX_EXECUTABLE_TARGETS}
|
||||
|
||||
# COMPRSSED_EXECUTABLES
|
||||
# Append to all defined executables the compression extentions to detect the
|
||||
# different make steps which compress the binary
|
||||
COMPRESSED_EXECUTABLES=$(UNIX_EXECUTABLES:%=%.tar.bz2) $(UNIX_EXECUTABLES:%=%.tar.gz) $(UNIX_EXECUTABLES:%=%.tar.xz)
|
||||
COMPRESSED_EXECUTABLE_TARGETS=$(COMPRESSED_EXECUTABLES:%=bin/%)
|
||||
COMPRESSED_EXECUTABLES:= \
|
||||
${UNIX_EXECUTABLES:%=%.tar.bz2} \
|
||||
${UNIX_EXECUTABLES:%=%.tar.gz} \
|
||||
${UNIX_EXECUTABLES:%=%.tar.xz} \
|
||||
${UNIX_EXECUTABLES:%=%.zip}
|
||||
COMPRESSED_EXECUTABLE_TARGETS:=${COMPRESSED_EXECUTABLES:%=bin/%}
|
||||
|
||||
# PHONY
|
||||
# To avoid a conflict with an existing file and a defined make step
|
||||
.PHONY: clean container/${EXECUTABLE_TARGETS} container/test release remote test
|
||||
# RPM_TARGETS
|
||||
RPM_EXECUTABLES:=${LINUX_EXECUTABLES:%=%.rpm}
|
||||
RPM_EXECUTABLE_TARGETS:=${RPM_EXECUTABLES:%=bin/%}
|
||||
|
||||
$(EXECUTABLE): bindata
|
||||
go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
# RELEASE_TARGETS
|
||||
RELEASE_EXECUTABLES:= \
|
||||
${COMPRESSED_EXECUTABLE_TARGETS} \
|
||||
${RPM_EXECUTABLE_TARGETS}
|
||||
|
||||
RELEASE_EXECUTABLE_TARGETS:= \
|
||||
${COMPRESSED_EXECUTABLE_TARGETS:%=release/%} \
|
||||
${RPM_EXECUTABLE_TARGETS:%=release/%}
|
||||
|
||||
# BINARIES
|
||||
# ==============================================================================
|
||||
# current os
|
||||
${EXECUTABLE}: bindata
|
||||
CGO_ENABLED=0 go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
# build all binaries
|
||||
PHONY:=all
|
||||
all: ${EXECUTABLE_TARGETS}
|
||||
|
||||
container/bin/tmp/${EXECUTABLE}:
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
# darwin os
|
||||
bin/darwin/386/${EXECUTABLE}: bindata
|
||||
CGO_ENABLED=0 GOARCH=386 GOOS=darwin go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
# 386
|
||||
bin/darwin/386/$(EXECUTABLE): bindata
|
||||
GOARCH=386 GOOS=darwin go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
bin/darwin/amd64/${EXECUTABLE}: bindata
|
||||
CGO_ENABLED=0 GOARCH=amd64 GOOS=darwin go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
bin/linux/386/$(EXECUTABLE): bindata
|
||||
GOARCH=386 GOOS=linux go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
# freebsd os
|
||||
bin/freebsd/amd64/${EXECUTABLE}: bindata
|
||||
CGO_ENABLED=0 GOARCH=amd64 GOOS=freebsd go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
# amd64
|
||||
bin/freebsd/amd64/$(EXECUTABLE): bindata
|
||||
GOARCH=amd64 GOOS=freebsd go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
# linux os
|
||||
bin/linux/386/${EXECUTABLE}: bindata
|
||||
CGO_ENABLED=0 GOARCH=386 GOOS=linux go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
bin/darwin/amd64/$(EXECUTABLE): bindata
|
||||
GOARCH=amd64 GOOS=darwin go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
bin/linux/amd64/${EXECUTABLE}: bindata
|
||||
CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
bin/linux/amd64/$(EXECUTABLE): bindata
|
||||
GOARCH=amd64 GOOS=linux go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
# arm
|
||||
bin/linux/arm/5/${EXECUTABLE}: bindata
|
||||
GOARM=5 GOARCH=arm go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
CGO_ENABLED=0 GOARM=5 GOARCH=arm GOOS=linux go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
bin/linux/arm/7/${EXECUTABLE}: bindata
|
||||
GOARM=7 GOARCH=arm go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
CGO_ENABLED=0 GOARM=7 GOARCH=arm GOOS=linux go build -ldflags "-X main.version=${VERSION}" -o "$@"
|
||||
|
||||
# GO-BINDATA
|
||||
# ==============================================================================
|
||||
bindata:
|
||||
go-bindata -pkg db -o ./pkg/db/bindataSQL.go ./pkg/db/sql/***
|
||||
go-bindata -pkg goldenfiles -o ./test/goldenfiles/bindata.go ./test/goldenfiles/json/***
|
||||
go-bindata -pkg db -o ./pkg/storage/db/bindataSQL.go ./pkg/storage/db/sql/*** ./pkg/storage/db/sql/psql/schema/***
|
||||
go-bindata -pkg goldenfiles -o ./test/goldenfiles/bindata.go ./test/goldenfiles/json
|
||||
|
||||
# TEST
|
||||
# ==============================================================================
|
||||
PHONY+=test test-update-all
|
||||
test: ${EXECUTABLE}
|
||||
go test -v ./...
|
||||
|
||||
test-update-all: ${EXECUTABLE}
|
||||
go test -v ./pkg/... -update all
|
||||
|
||||
# PACKAGES
|
||||
# ==============================================================================
|
||||
%.rpm: %
|
||||
rpm-builder \
|
||||
--exec-file "$<:/usr/bin/${EXECUTABLE}" \
|
||||
--dir "systemd:/usr/lib/systemd/system" \
|
||||
--license AGFA_PROPERTERY \
|
||||
--version ${VERSION} \
|
||||
--release ${RELEASE} \
|
||||
--out $@ \
|
||||
${EXECUTABLE}
|
||||
|
||||
# RELEASE
|
||||
# ==============================================================================
|
||||
PHONY+=release/all
|
||||
release/all: clean ${RELEASE_EXECUTABLES}
|
||||
|
||||
github-release release \
|
||||
--user ${GITHUB_USER} \
|
||||
--repo ${EXECUTABLE} \
|
||||
--tag ${VERSION}
|
||||
|
||||
$(foreach FILE,${RELEASE_EXECUTABLES},github-release upload --user ${GITHUB_USER} --repo ${EXECUTABLE} --tag ${VERSION} --name $(subst /,-,${FILE}) --file bin/${FILE} --replace;)
|
||||
|
||||
PHONY+=${RELEASE_EXECUTABLE_TARGETS}
|
||||
${RELEASE_EXECUTABLE_TARGETS}: clean
|
||||
$(MAKE) $(subst release/,,$@)
|
||||
|
||||
github-release release \
|
||||
--user ${GITHUB_USER} \
|
||||
--repo ${EXECUTABLE} \
|
||||
--tag ${VERSION}
|
||||
|
||||
github-release upload \
|
||||
--user ${GITHUB_USER} \
|
||||
--repo ${EXECUTABLE} \
|
||||
--tag ${VERSION} \
|
||||
--name $(subst /,-,$(subst release/bin/,,$@)) \
|
||||
--file $(subst release/,,$@) \
|
||||
--replace
|
||||
|
||||
# COMPRESSION
|
||||
# ==============================================================================
|
||||
%.tar.bz2: %
|
||||
tar --create --bzip2 --file "$@" "$<"
|
||||
|
||||
@@ -98,66 +193,88 @@ bindata:
|
||||
%.tar.xz: %
|
||||
tar --create --xz --file "$@" "$<"
|
||||
|
||||
%.zip: %
|
||||
zip "$@" "$<"
|
||||
|
||||
test: ${EXECUTABLE}
|
||||
go test -v ./pkg/...
|
||||
|
||||
release: clean
|
||||
$(MAKE) $(COMPRESSED_EXECUTABLE_TARGETS)
|
||||
github-release release \
|
||||
--user ${GITHUB_USER} \
|
||||
--repo ${EXECUTABLE} \
|
||||
--tag ${VERSION}
|
||||
|
||||
$(foreach FILE,$(COMPRESSED_EXECUTABLES),github-release upload --user ${GITHUB_USER} --repo ${EXECUTABLE} --tag ${VERSION} --name $(subst /,-,$(FILE)) --file bin/$(FILE) --replace;)
|
||||
|
||||
|
||||
# OTHER STUFF
|
||||
# ==============================================================================
|
||||
PHONY+=clean
|
||||
clean:
|
||||
rm ${EXECUTABLE} || true
|
||||
rm ${EXECUTABLE}.* || true
|
||||
rm --recursive --force bin/ || true
|
||||
|
||||
|
||||
# CONTAINER IMAGE STEPS
|
||||
# ==============================================================================
|
||||
PHONY+=container-image/build/amd64
|
||||
container-image/build/amd64: bin/linux/amd64/${EXECUTABLE}
|
||||
${CONTAINER_RUNTIME} build \
|
||||
--tag volkerraschek/${EXECUTABLE}:${IMAGE_VERSION} \
|
||||
.
|
||||
|
||||
PHONY+=container-image/push/amd64
|
||||
container-image/push/amd64: container-image/build/amd64
|
||||
${CONTAINER_RUNTIME} push volkerraschek/${EXECUTABLE}:${IMAGE_VERSION}
|
||||
|
||||
# container
|
||||
container/${EXECUTABLE}:
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
# CONTAINER STEPS - BINARY
|
||||
# ==============================================================================
|
||||
# current os
|
||||
PHONY+=container-run/${EXECUTABLE}
|
||||
container-run/${EXECUTABLE}:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
container/all:
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
# build all binaries for any operating system
|
||||
PHONY+=container-run/all
|
||||
container-run/all:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
container/test:
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
PHONY+=${UNIX_EXECUTABLE_TARGETS:%=container-run/%}
|
||||
${UNIX_EXECUTABLE_TARGETS:%=container-run/%}:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
container/release:
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
# CONTAINER STEPS - GO-BINDATA
|
||||
# ==============================================================================
|
||||
PHONY+=container-run/bindata
|
||||
container-run/bindata:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
# container - 386
|
||||
container/bin/darwin/386/$(EXECUTABLE):
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
# CONTAINER STEPS - TEST
|
||||
# ==============================================================================
|
||||
PHONY+=container-run/test
|
||||
container-run/test:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
container/bin/linux/386/$(EXECUTABLE):
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
PHONY+=container-run/test-update-all
|
||||
container-run/test-update-all:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
# container - amd
|
||||
container/bin/freebsd/amd64/$(EXECUTABLE):
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
# CONTAINER STEPS - COMPRESSED BINARIES AND PACKAGES
|
||||
# ==============================================================================
|
||||
PHONY+=${COMPRESSED_EXECUTABLE_TARGETS:%=container-run/%}
|
||||
${COMPRESSED_EXECUTABLE_TARGETS:%=container-run/%}:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
container/bin/darwin/amd64/$(EXECUTABLE):
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
PHONY+=${RPM_EXECUTABLE_TARGETS:%=container-run/%}
|
||||
${RPM_EXECUTABLE_TARGETS:%=container-run/%}:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
container/bin/linux/amd64/$(EXECUTABLE):
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
# CONTAINER STEPS - RELEASE COMPRESSED BINARIES AND PACKAGES
|
||||
# ==============================================================================
|
||||
PHONY+=${RELEASE_EXECUTABLE_TARGETS%=container-run/%}
|
||||
${RELEASE_EXECUTABLE_TARGETS:%=container-run/%}:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
# container - arm
|
||||
container/bin/linux/arm/7/${EXECUTABLE}:
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
# CONTAINER STEPS - OTHER STUF
|
||||
# ==============================================================================
|
||||
PHONY+=container-run/clean
|
||||
container-run/clean:
|
||||
$(MAKE) container-run/ COMMAND=$(subst container-run/,,$@)
|
||||
|
||||
container/bin/linux/arm/5/${EXECUTABLE}:
|
||||
$(MAKE) container-run COMMAND=$(subst container/,,$@)
|
||||
|
||||
|
||||
container-run:
|
||||
# GENERAL CONTAINER COMMAND
|
||||
# ==============================================================================
|
||||
PHONY+=container-run/
|
||||
container-run/:
|
||||
${CONTAINER_RUNTIME} run \
|
||||
--rm \
|
||||
--volume ${PWD}:/workspace \
|
||||
@@ -166,8 +283,17 @@ container-run:
|
||||
UID=${UID} \
|
||||
GID=${GID} \
|
||||
VERSION=${VERSION} \
|
||||
GITHUB_TOKEN=${GITHUB_TOKEN}
|
||||
RELEASE=${RELEASE}
|
||||
|
||||
remote: bin/linux/arm/7/${EXECUTABLE}
|
||||
scp bin/linux/arm/7/${EXECUTABLE} ${FLUCKY_REMOTE}:/usr/local/bin
|
||||
ssh ${FLUCKY_REMOTE} "chmod +x /usr/local/bin/flucky"
|
||||
# REMOTE
|
||||
# ==============================================================================
|
||||
PHONY+=${FLUCKY_REMOTE:%=remote/%}
|
||||
remote/${FLUCKY_REMOTE}: bin/linux/arm/7/${EXECUTABLE}
|
||||
scp bin/linux/arm/7/${EXECUTABLE} root@${FLUCKY_REMOTE}:/usr/local/bin/${EXECUTABLE}
|
||||
ssh root@${FLUCKY_REMOTE} 'chmod +x /usr/local/bin/${EXECUTABLE}'
|
||||
|
||||
# PHONY
|
||||
# ==============================================================================
|
||||
# Declare the contents of the PHONY variable as phony. We keep that information
|
||||
# in a variable so we can use it in if_changed.
|
||||
.PHONY: ${PHONY}
|
||||
+10
-10
@@ -47,9 +47,9 @@ var rootCmd = &cobra.Command{
|
||||
Device: &types.Device{
|
||||
DeviceID: uuid.NewV4().String(),
|
||||
DeviceName: hostname,
|
||||
Logfile: "/var/log/flucky/logfile.csv",
|
||||
CreationDate: t,
|
||||
},
|
||||
Logfile: "/var/log/flucky/logfile.csv",
|
||||
}
|
||||
|
||||
err = config.Write(&cnf, configFile)
|
||||
@@ -68,14 +68,14 @@ func Execute(version *semver.Version) {
|
||||
|
||||
rootCmd.PersistentFlags().StringVar(&configFile, "config", "/etc/flucky/config.json", "Config file")
|
||||
|
||||
compression.InitCmd(rootCmd, &configFile)
|
||||
convert.InitCmd(rootCmd, &configFile)
|
||||
daemon.InitCmd(rootCmd, &configFile)
|
||||
// db.InitCmd(rootCmd, &configFile)
|
||||
humidity.InitCmd(rootCmd, &configFile)
|
||||
pressure.InitCmd(rootCmd, &configFile)
|
||||
rgbled.InitCmd(rootCmd, &configFile)
|
||||
sensor.InitCmd(rootCmd, &configFile)
|
||||
temperature.InitCmd(rootCmd, &configFile)
|
||||
compression.InitCmd(rootCmd, &configFile, version)
|
||||
convert.InitCmd(rootCmd, &configFile, version)
|
||||
daemon.InitCmd(rootCmd, &configFile, version)
|
||||
// db.InitCmd(rootCmd, &configFile, version)
|
||||
humidity.InitCmd(rootCmd, &configFile, version)
|
||||
pressure.InitCmd(rootCmd, &configFile, version)
|
||||
rgbled.InitCmd(rootCmd, &configFile, version)
|
||||
sensor.InitCmd(rootCmd, &configFile, version)
|
||||
temperature.InitCmd(rootCmd, &configFile, version)
|
||||
rootCmd.Execute()
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"log"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"log"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -37,13 +37,13 @@ var daemonCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
logger := logger.NewDefaultLogger(logger.LogLevelDebug)
|
||||
|
||||
daemon.Start(cnf, duration, compression, round, logger)
|
||||
daemon.SetLogger(logger)
|
||||
daemon.Start(cnf, duration, compression, round, version)
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
func InitCmd(cmd *cobra.Command, cnfFile *string, sverion *semver.Version) {
|
||||
func InitCmd(cmd *cobra.Command, cnfFile *string, sversion *semver.Version) {
|
||||
configFile = cnfFile
|
||||
version = sversion
|
||||
|
||||
|
||||
+9
-2
@@ -5,7 +5,8 @@ import (
|
||||
"log"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
database "github.com/go-flucky/flucky/pkg/db"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
database "github.com/go-flucky/flucky/pkg/storage/db"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -21,7 +22,13 @@ var dbCmd = &cobra.Command{
|
||||
Short: "Operates with the configured database",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
postgresDB, err := database.New(database.DBOTypePostgres, "localhost", "5432", "postgres", "postgres", "postgres")
|
||||
// read configuration
|
||||
cnf, err := config.Read(*configFile)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
postgresDB, err := database.New(cnf.DatabaseSettings)
|
||||
if err != nil {
|
||||
log.Fatalf("%v", err)
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/cli"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/rgbled"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -26,7 +26,7 @@ var listTemperatureCmd = &cobra.Command{
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
logfile := logfile.New(cnf.Device.Logfile)
|
||||
logfile := logfile.New(cnf.Logfile)
|
||||
|
||||
rgbLEDs := cnf.GetRGBLEDs(config.ENABLED)
|
||||
if err := rgbled.Logfile(rgbLEDs); err != nil {
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/cli"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/rgbled"
|
||||
"github.com/go-flucky/flucky/pkg/sensor"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -56,7 +56,7 @@ var readHumidityCmd = &cobra.Command{
|
||||
cli.PrintMeasuredValues(measuredValues, cnf, os.Stdout)
|
||||
|
||||
if logs {
|
||||
measuredValuesLogfile := logfile.New(cnf.Device.Logfile)
|
||||
measuredValuesLogfile := logfile.New(cnf.Logfile)
|
||||
err := logfile.Append(measuredValuesLogfile, compression, round, measuredValues)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
|
||||
@@ -5,12 +5,11 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/cli"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/rgbled"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -26,7 +25,7 @@ var listTemperatureCmd = &cobra.Command{
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
logfile := logfile.New(cnf.Device.Logfile)
|
||||
logfile := logfile.New(cnf.Logfile)
|
||||
|
||||
rgbLEDs := cnf.GetRGBLEDs(config.ENABLED)
|
||||
if err := rgbled.Logfile(rgbLEDs); err != nil {
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/cli"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/rgbled"
|
||||
"github.com/go-flucky/flucky/pkg/sensor"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -56,7 +56,7 @@ var readPressureCmd = &cobra.Command{
|
||||
cli.PrintMeasuredValues(measuredValues, cnf, os.Stdout)
|
||||
|
||||
if logs {
|
||||
measuredValuesLogfile := logfile.New(cnf.Device.Logfile)
|
||||
measuredValuesLogfile := logfile.New(cnf.Logfile)
|
||||
err := logfile.Append(measuredValuesLogfile, compression, round, measuredValues)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/cli"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/rgbled"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -26,7 +26,7 @@ var listTemperatureCmd = &cobra.Command{
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
logfile := logfile.New(cnf.Device.Logfile)
|
||||
logfile := logfile.New(cnf.Logfile)
|
||||
|
||||
rgbLEDs := cnf.GetRGBLEDs(config.ENABLED)
|
||||
if err := rgbled.Logfile(rgbLEDs); err != nil {
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/rgbled"
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/cli"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/sensor"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -60,7 +60,7 @@ var readTemperatureCmd = &cobra.Command{
|
||||
cli.PrintMeasuredValues(measuredValues, cnf, os.Stdout)
|
||||
|
||||
if logs {
|
||||
measuredValuesLogfile := logfile.New(cnf.Device.Logfile)
|
||||
measuredValuesLogfile := logfile.New(cnf.Logfile)
|
||||
err := logfile.Append(measuredValuesLogfile, compression, round, measuredValues)
|
||||
if err != nil {
|
||||
rgbled.Error(rgbLEDs)
|
||||
|
||||
@@ -7,10 +7,16 @@ require (
|
||||
github.com/d2r2/go-bsbmp v0.0.0-20190515110334-3b4b3aea8375
|
||||
github.com/d2r2/go-i2c v0.0.0-20181113114621-14f8dd4e89ce
|
||||
github.com/d2r2/go-logger v0.0.0-20181221090742-9998a510495e
|
||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||
github.com/docker/docker v1.13.1 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/go-flucky/go-dht v0.1.1
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/lib/pq v1.2.0
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.3 // indirect
|
||||
|
||||
@@ -8,6 +8,14 @@ github.com/d2r2/go-logger v0.0.0-20181221090742-9998a510495e h1:ZG3JBA6rPRl0xxQ+
|
||||
github.com/d2r2/go-logger v0.0.0-20181221090742-9998a510495e/go.mod h1:oA+9PUt8F1aKJ6o4YU1T120i7sgo1T6/1LWEEBy0BSs=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=
|
||||
github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/go-flucky/go-dht v0.1.1 h1:dPz9F5D7oUaTd0GUGTvT4lBH2R043h1bkmhTlpQax1Y=
|
||||
github.com/go-flucky/go-dht v0.1.1/go.mod h1:Yk/cct+/u+eCS7pB/kc0tc7MrVXdFI4W15MJCj5FRUc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
@@ -19,6 +27,10 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
@@ -33,6 +45,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
||||
@@ -29,9 +29,9 @@ func main() {
|
||||
|
||||
sversion, err := semver.NewVersion(version)
|
||||
if err != nil {
|
||||
log.Println("The sematic versioning is invalid: %v", version)
|
||||
log.Printf("The sematic versioning is invalid: %v", version)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cmd.Execute(version)
|
||||
cmd.Execute(sversion)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package config
|
||||
|
||||
type DatabaseSettings struct {
|
||||
Vendor DatabaseVendor `json:"vendor"`
|
||||
Host string `json:"host"`
|
||||
Port string `json:"port"`
|
||||
Database string `json:"database"`
|
||||
User string `json:"user"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type DatabaseVendor string
|
||||
|
||||
func (dv DatabaseVendor) String() string {
|
||||
return string(dv)
|
||||
}
|
||||
|
||||
const (
|
||||
VendorPostgreSQL DatabaseVendor = "postgres"
|
||||
VendorOracle = "oracle"
|
||||
)
|
||||
@@ -32,7 +32,9 @@ var temperatureSensorModels = map[types.SensorModel]types.SensorModel{
|
||||
|
||||
// Configuration of flucky
|
||||
type Configuration struct {
|
||||
DatabaseSettings *DatabaseSettings `json:"database_settings"`
|
||||
Device *types.Device `json:"device"`
|
||||
Logfile string `json:"logfile" xml:"logfile"`
|
||||
RGBLEDs []*types.RGBLED `json:"rgb_leds"`
|
||||
Sensors []*types.Sensor `json:"sensors"`
|
||||
}
|
||||
@@ -451,6 +453,11 @@ func (c *Configuration) GetTemperatureSensorsByName(names []string) []sensor.Sen
|
||||
return c.convertSensors(temperatureSensors)
|
||||
}
|
||||
|
||||
// RemoveDatabaseSettings remove data base setting informations
|
||||
func (c *Configuration) RemoveDatabaseSettings() {
|
||||
c.DatabaseSettings = nil
|
||||
}
|
||||
|
||||
// RemoveRGBLED deletes a LED by its name or its unique UUID
|
||||
func (c *Configuration) RemoveRGBLED(name string) error {
|
||||
for i, rgbLED := range c.RGBLEDs {
|
||||
@@ -513,6 +520,11 @@ func (c *Configuration) RenameSensor(oldName, newName string) error {
|
||||
return fmt.Errorf("Could not find remote %v to replace into with %v", oldName, newName)
|
||||
}
|
||||
|
||||
// SetDatabaseSettings set database setting informations
|
||||
func (c *Configuration) SetDatabaseSettings(databaseSettings *DatabaseSettings) {
|
||||
c.DatabaseSettings = databaseSettings
|
||||
}
|
||||
|
||||
func (c *Configuration) convertSensors(sensors []*types.Sensor) []sensor.Sensor {
|
||||
cachedSensors := make([]sensor.Sensor, 0)
|
||||
|
||||
|
||||
+84
-37
@@ -7,12 +7,13 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/db"
|
||||
"github.com/go-flucky/flucky/pkg/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/logger"
|
||||
"github.com/go-flucky/flucky/pkg/rgbled"
|
||||
"github.com/go-flucky/flucky/pkg/sensor"
|
||||
"github.com/go-flucky/flucky/pkg/storage/db"
|
||||
"github.com/go-flucky/flucky/pkg/storage/logfile"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
)
|
||||
|
||||
@@ -22,15 +23,25 @@ var (
|
||||
postgresDatabase = "postgres"
|
||||
postgresUser = "postgres"
|
||||
postgresPassword = "postgres"
|
||||
|
||||
flogger logger.Logger
|
||||
)
|
||||
|
||||
func init() {
|
||||
flogger = logger.NewSilentLogger()
|
||||
}
|
||||
|
||||
func SetLogger(logger logger.Logger) {
|
||||
flogger = logger
|
||||
}
|
||||
|
||||
// Start the daemon
|
||||
func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compression bool, round float64, logger logger.Logger) {
|
||||
func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compression bool, round float64, version *semver.Version) {
|
||||
|
||||
// Info
|
||||
logger.Info("Use clean-cache-interval: %v", cleanCacheInterval.String())
|
||||
logger.Info("Use compression: %v", compression)
|
||||
logger.Info("Round: %v", round)
|
||||
flogger.Info("Use clean-cache-interval: %v", cleanCacheInterval.String())
|
||||
flogger.Info("Use compression: %v", compression)
|
||||
flogger.Info("Round: %v", round)
|
||||
|
||||
ticker := time.Tick(cleanCacheInterval)
|
||||
|
||||
@@ -43,29 +54,44 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress
|
||||
ctx := context.Background()
|
||||
childContext, cancel := context.WithCancel(ctx)
|
||||
|
||||
measuredValuesLogfile := logfile.New(cnf.Device.Logfile)
|
||||
measuredValuesLogfile := logfile.New(cnf.Logfile)
|
||||
|
||||
measuredValuesCache := make([]*types.MeasuredValue, 0)
|
||||
|
||||
go sensor.ReadContinuously(childContext, cnf.GetSensors(config.ENABLED), measuredValuesChannel, errorChannel)
|
||||
var postgres db.Database
|
||||
if cnf.DatabaseSettings != nil {
|
||||
p, err := db.New(cnf.DatabaseSettings)
|
||||
if err != nil {
|
||||
flogger.Error("%v", err)
|
||||
}
|
||||
if err := p.Schema(ctx, version); err != nil {
|
||||
flogger.Error("%v", err)
|
||||
}
|
||||
postgres = p
|
||||
checkDeviceInDatabase(ctx, cnf.Device, postgres)
|
||||
checkSensorsInDatabase(ctx, cnf.Sensors, postgres)
|
||||
defer postgres.Close()
|
||||
}
|
||||
|
||||
rgbLEDs := cnf.GetRGBLEDs(config.ENABLED)
|
||||
|
||||
go sensor.ReadContinuously(childContext, cnf.GetSensors(config.ENABLED), measuredValuesChannel, errorChannel)
|
||||
|
||||
for {
|
||||
|
||||
err := rgbled.Run(rgbLEDs)
|
||||
if err != nil {
|
||||
logger.Error("Can not turn on green info light: %v", err)
|
||||
flogger.Error("Can not turn on green info light: %v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case err, _ := <-errorChannel:
|
||||
|
||||
logger.Error("%v", err)
|
||||
flogger.Error("%v", err)
|
||||
|
||||
err = rgbled.Error(rgbLEDs)
|
||||
if err != nil {
|
||||
logger.Error("Can not turn on red info light: %v", err)
|
||||
flogger.Error("Can not turn on red info light: %v", err)
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 2)
|
||||
@@ -73,34 +99,25 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress
|
||||
case <-ticker:
|
||||
err := rgbled.Logfile(rgbLEDs)
|
||||
if err != nil {
|
||||
logger.Error("Can not turn on blue info light: %v", err)
|
||||
flogger.Error("Can not turn on blue info light: %v", err)
|
||||
}
|
||||
|
||||
// err = logfile.Append(measuredValuesLogfile, compression, round, measuredValuesCache)
|
||||
|
||||
postgres, err := db.New(db.DBOTypePostgres, postgresHost, postgresPort, postgresDatabase, postgresUser, postgresPassword)
|
||||
if err != nil {
|
||||
|
||||
err = rgbled.Error(rgbLEDs)
|
||||
if err != nil {
|
||||
logger.Error("Can not turn on red info light: %v", err)
|
||||
if err := logfile.Append(measuredValuesLogfile, compression, round, measuredValuesCache); err != nil {
|
||||
err2 := rgbled.Error(rgbLEDs)
|
||||
if err2 != nil {
|
||||
flogger.Error("Can not turn on red info light: %v", err2)
|
||||
}
|
||||
flogger.Error("Can not save caches measured values in logfile: %v", err)
|
||||
}
|
||||
|
||||
cancel()
|
||||
logger.Error("Can not open database connection: %v", err)
|
||||
if postgres != nil {
|
||||
if err := postgres.InsertMeasuredValues(ctx, measuredValuesCache); err != nil {
|
||||
err2 := rgbled.Error(rgbLEDs)
|
||||
if err2 != nil {
|
||||
flogger.Error("Can not turn on red info light: %v", err)
|
||||
}
|
||||
|
||||
postgresCtx := context.Background()
|
||||
err = postgres.InsertMeasuredValues(postgresCtx, measuredValuesCache)
|
||||
if err != nil {
|
||||
|
||||
err = rgbled.Error(rgbLEDs)
|
||||
if err != nil {
|
||||
logger.Error("Can not turn on red info light: %v", err)
|
||||
flogger.Error("Can not save cached measured values in database: %v", err)
|
||||
}
|
||||
|
||||
cancel()
|
||||
logger.Error("Can not save caches measured values in database: %v", err)
|
||||
}
|
||||
|
||||
measuredValuesCache = make([]*types.MeasuredValue, 0)
|
||||
@@ -109,22 +126,52 @@ func Start(cnf *config.Configuration, cleanCacheInterval time.Duration, compress
|
||||
measuredValuesCache = append(measuredValuesCache, measuredValues...)
|
||||
|
||||
case killSignal := <-interrupt:
|
||||
logger.Warn("Daemon was interruped by system signal %v\n", killSignal)
|
||||
flogger.Warn("Daemon was interruped by system signal %v\n", killSignal)
|
||||
|
||||
cancel()
|
||||
|
||||
err := rgbled.Error(rgbLEDs)
|
||||
if err != nil {
|
||||
logger.Error("Can not turn on red info light: %v", err)
|
||||
flogger.Error("Can not turn on red info light: %v", err)
|
||||
}
|
||||
|
||||
logger.Warn("Save remaining data from the cache")
|
||||
flogger.Warn("Save remaining data from the cache")
|
||||
err = logfile.Append(measuredValuesLogfile, compression, round, measuredValuesCache)
|
||||
if err != nil {
|
||||
logger.Fatal("%v", err)
|
||||
flogger.Fatal("%v", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkDeviceInDatabase(ctx context.Context, device *types.Device, database db.Database) {
|
||||
_, err := database.SelectDeviceByID(ctx, device.DeviceID)
|
||||
if err != nil {
|
||||
flogger.Debug("It's seems the current device is not registered in the database. Register the device now")
|
||||
err2 := database.InsertDevices(ctx, []*types.Device{device})
|
||||
if err2 != nil {
|
||||
flogger.Fatal("Can not register device into database: %v", err2)
|
||||
}
|
||||
flogger.Debug("Device successfully registered into the database")
|
||||
return
|
||||
}
|
||||
flogger.Debug("Device already registered into the database")
|
||||
}
|
||||
|
||||
func checkSensorsInDatabase(ctx context.Context, sensors []*types.Sensor, database db.Database) {
|
||||
for _, sensor := range sensors {
|
||||
_, err := database.SelectSensorByID(ctx, sensor.SensorID)
|
||||
if err != nil {
|
||||
flogger.Debug("It's seems the sensor %v is not registered in the database. Register the sensor now", sensor.SensorName)
|
||||
err2 := database.InsertSensors(ctx, []*types.Sensor{sensor})
|
||||
if err2 != nil {
|
||||
flogger.Fatal("Can not register sensor %v into database: %v", sensor.SensorName, err2)
|
||||
}
|
||||
flogger.Debug("Sensor %v successfully registered into the database", sensor.SensorName)
|
||||
continue
|
||||
}
|
||||
flogger.Debug("Sensor %v is already registered into the database", sensor.SensorName)
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
func New(dboType DBOType, host string, port string, database string, user string, password string) (Database, error) {
|
||||
connStr := fmt.Sprintf("%v://%v:%v@%v:%v/%v?sslmode=disable", dboType.String(), user, password, host, port, database)
|
||||
newDBO, err := sql.Open(dboType.String(), connStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch dboType {
|
||||
case "postgres":
|
||||
return &Postgres{
|
||||
dbo: newDBO,
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown Database Type")
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package db
|
||||
|
||||
type DBOType string
|
||||
|
||||
func (dboType DBOType) String() string {
|
||||
return string(dboType)
|
||||
}
|
||||
|
||||
const (
|
||||
DBOTypePostgres DBOType = "postgres"
|
||||
DBOTypeOracle = "oracle"
|
||||
)
|
||||
@@ -1,10 +0,0 @@
|
||||
package db
|
||||
|
||||
var (
|
||||
postgreSQLSchemata []*schemaInformation
|
||||
)
|
||||
|
||||
type schemaInformation struct {
|
||||
Version string
|
||||
Asset string
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,39 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/logger"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var (
|
||||
flogger logger.Logger
|
||||
)
|
||||
|
||||
func init() {
|
||||
flogger = logger.NewSilentLogger()
|
||||
}
|
||||
|
||||
func New(databaseSettings *config.DatabaseSettings) (Database, error) {
|
||||
connStr := fmt.Sprintf("%v://%v:%v@%v:%v/%v?sslmode=disable", databaseSettings.Vendor.String(), databaseSettings.User, databaseSettings.Password, databaseSettings.Host, databaseSettings.Port, databaseSettings.Database)
|
||||
newDBO, err := sql.Open(databaseSettings.Vendor.String(), connStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch databaseSettings.Vendor {
|
||||
case config.VendorPostgreSQL:
|
||||
return &Postgres{
|
||||
dbo: newDBO,
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown Database Type")
|
||||
}
|
||||
}
|
||||
|
||||
func SetLogger(logger logger.Logger) {
|
||||
flogger = logger
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
@@ -5,6 +5,7 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
@@ -13,71 +14,91 @@ import (
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var (
|
||||
postgresAssetPath = "pkg/storage/db/sql/psql"
|
||||
)
|
||||
|
||||
type Postgres struct {
|
||||
dbo *sql.DB
|
||||
}
|
||||
|
||||
func (p *Postgres) Close() error {
|
||||
return p.Close()
|
||||
return p.dbo.Close()
|
||||
}
|
||||
|
||||
// Schema create or upgrade database schema to the version of the flucky binary
|
||||
func (p *Postgres) Schema(ctx context.Context, version *semver.Version) error {
|
||||
|
||||
query := "SELECT value FROM info WHERE key='version';"
|
||||
schemaFunc := func(ctx context.Context, fromVersion *semver.Version, toVersion *semver.Version) error {
|
||||
|
||||
stmt, err := p.dbo.PrepareContext(ctx, query)
|
||||
assetPath := fmt.Sprintf("%v/schema", postgresAssetPath)
|
||||
sqlAssetFiles, err := AssetDir(assetPath)
|
||||
if err != nil {
|
||||
|
||||
asset := "pkg/db/sql/psql/schema.sql"
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
return fmt.Errorf("Can not restore asset directory %v: %v", assetPath, err)
|
||||
}
|
||||
query = string(queryBytes)
|
||||
|
||||
_, err = p.dbo.ExecContext(ctx, query)
|
||||
postgreSQLVersionChanges := make(map[*semver.Version]string, 0)
|
||||
postgreSQLVersions := make([]*semver.Version, len(sqlAssetFiles))
|
||||
|
||||
for i, sqlAssetFile := range sqlAssetFiles {
|
||||
fileSemVersion, err := semver.NewVersion(strings.ReplaceAll(sqlAssetFile, ".sql", ""))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Can not create semantic version from file asset %v: %v", sqlAssetFile, err)
|
||||
}
|
||||
postgreSQLVersionChanges[fileSemVersion] = sqlAssetFile
|
||||
postgreSQLVersions[i] = fileSemVersion
|
||||
}
|
||||
sort.Sort(semver.Collection(postgreSQLVersions))
|
||||
|
||||
for i, postgreSQLVersion := range postgreSQLVersions {
|
||||
if fromVersion != nil {
|
||||
if postgreSQLVersion.LessThan(fromVersion) || postgreSQLVersion.Equal(fromVersion) {
|
||||
flogger.Debug("SKIP: PostgreSQL schema version '%v' is less or eqal then the local version changes '%v'", postgreSQLVersion.String(), fromVersion.String())
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
asset := postgreSQLVersionChanges[postgreSQLVersion]
|
||||
queryBytes, err := Asset(filepath.Join(assetPath, asset))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Can not restore asset %v, %v", asset, err)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
if _, err := p.dbo.ExecContext(ctx, query); err != nil {
|
||||
return fmt.Errorf("%v: %v", errorStatementExecute, err)
|
||||
}
|
||||
|
||||
if i == 0 {
|
||||
if err := p.InsertInfo(ctx, "version", postgreSQLVersion.String()); err != nil {
|
||||
return fmt.Errorf("Can not insert version %v into info table: %v", postgreSQLVersion.String(), err)
|
||||
}
|
||||
} else {
|
||||
if err := p.UpdateInfo(ctx, "version", postgreSQLVersion.String()); err != nil {
|
||||
return fmt.Errorf("Can not update version %v into info table: %v", postgreSQLVersion.String(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
schemaVersion := ""
|
||||
row := stmt.QueryRowContext(ctx)
|
||||
err = row.Scan(&schemaVersion)
|
||||
dbVersion, err := p.SelectInfo(ctx, "version")
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorScanRow, err)
|
||||
}
|
||||
|
||||
fromVersion, err := semver.NewVersion(schemaVersion)
|
||||
// can not select version from database, maybe the schema is not initialize
|
||||
// create db schema for the current flucky version
|
||||
return schemaFunc(ctx, nil, version)
|
||||
} else {
|
||||
fromVersion, err := semver.NewVersion(dbVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Can not create new sematic version from database: %v", err)
|
||||
return fmt.Errorf("Can not create semantic version from database entry %v: %v", dbVersion, err)
|
||||
}
|
||||
|
||||
if err := schema(fromVersion, version); err != nil {
|
||||
return err
|
||||
return schemaFunc(ctx, fromVersion, version)
|
||||
}
|
||||
|
||||
// The result will be 0 if from == to, -1 if from < to, or +1 if from > to.
|
||||
switch fromVersion.Compare(version) {
|
||||
case -1:
|
||||
return schema(fromVersion, version)
|
||||
case 0:
|
||||
// fromVersion and toVersion are equal
|
||||
return nil
|
||||
case 1:
|
||||
// fromVersion < toVersion
|
||||
return fmt.Errorf("Can not downgrade the database schema. Update the flucky binary")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (p *Postgres) DeleteDevices(ctx context.Context, devices []*types.Device) error {
|
||||
asset := "pkg/db/sql/psql/deleteDevice.sql"
|
||||
asset := fmt.Sprintf("%v/deleteDevice.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -101,7 +122,7 @@ func (p *Postgres) DeleteDevices(ctx context.Context, devices []*types.Device) e
|
||||
}
|
||||
|
||||
func (p *Postgres) DeleteSensors(ctx context.Context, sensors []*types.Sensor) error {
|
||||
asset := "pkg/db/sql/psql/deleteSensor.sql"
|
||||
asset := fmt.Sprintf("%v/deleteSensor.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -161,7 +182,7 @@ func (p *Postgres) DeleteMeasuredValues(ctx context.Context, measuredValues []*t
|
||||
for measuredValueType, sortedMeasuredValues := range sortedMeasuredValueTypes {
|
||||
switch measuredValueType {
|
||||
case types.MeasuredValueTypeHumidity:
|
||||
query, err := assetFunc("pkg/db/sql/psql/deleteHumidity.sql")
|
||||
query, err := assetFunc(fmt.Sprintf("%v/deleteHumidity.sql", postgresAssetPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -170,7 +191,7 @@ func (p *Postgres) DeleteMeasuredValues(ctx context.Context, measuredValues []*t
|
||||
return err
|
||||
}
|
||||
case types.MeasuredValueTypePressure:
|
||||
query, err := assetFunc("pkg/db/sql/psql/deletePressure.sql")
|
||||
query, err := assetFunc(fmt.Sprintf("%v/deletePressure.sql", postgresAssetPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -179,7 +200,7 @@ func (p *Postgres) DeleteMeasuredValues(ctx context.Context, measuredValues []*t
|
||||
return err
|
||||
}
|
||||
case types.MeasuredValueTypeTemperature:
|
||||
query, err := assetFunc("pkg/db/sql/psql/deleteTemperature.sql")
|
||||
query, err := assetFunc(fmt.Sprintf("%v/deleteTemperature.sql", postgresAssetPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -194,7 +215,7 @@ func (p *Postgres) DeleteMeasuredValues(ctx context.Context, measuredValues []*t
|
||||
}
|
||||
|
||||
func (p *Postgres) InsertDevices(ctx context.Context, devices []*types.Device) error {
|
||||
asset := "pkg/db/sql/psql/insertDevice.sql"
|
||||
asset := fmt.Sprintf("%v/insertDevice.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -217,6 +238,28 @@ func (p *Postgres) InsertDevices(ctx context.Context, devices []*types.Device) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Postgres) InsertInfo(ctx context.Context, key string, value string) error {
|
||||
asset := fmt.Sprintf("%v/insertInfo.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
stmt, err := p.dbo.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorPrepareStatement, err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
_, err = stmt.ExecContext(ctx, key, value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorStatementExecute, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Postgres) InsertMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error {
|
||||
|
||||
sortedMeasuredValueTypes := make(map[types.MeasuredValueType][]*types.MeasuredValue)
|
||||
@@ -250,7 +293,7 @@ func (p *Postgres) InsertMeasuredValues(ctx context.Context, measuredValues []*t
|
||||
|
||||
func (p *Postgres) insertHumidity(ctx context.Context, measuredValues []*types.MeasuredValue) error {
|
||||
|
||||
asset := "pkg/db/sql/psql/insertHumidity.sql"
|
||||
asset := fmt.Sprintf("%v/insertHumidity.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -279,7 +322,7 @@ func (p *Postgres) insertHumidity(ctx context.Context, measuredValues []*types.M
|
||||
|
||||
func (p *Postgres) insertPressure(ctx context.Context, measuredValues []*types.MeasuredValue) error {
|
||||
|
||||
asset := "pkg/db/sql/psql/insertPressure.sql"
|
||||
asset := fmt.Sprintf("%v/insertPressure.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -308,7 +351,7 @@ func (p *Postgres) insertPressure(ctx context.Context, measuredValues []*types.M
|
||||
|
||||
func (p *Postgres) insertTemperature(ctx context.Context, measuredValues []*types.MeasuredValue) error {
|
||||
|
||||
asset := "pkg/db/sql/psql/insertTemperature.sql"
|
||||
asset := fmt.Sprintf("%v/insertTemperature.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -337,7 +380,7 @@ func (p *Postgres) insertTemperature(ctx context.Context, measuredValues []*type
|
||||
|
||||
func (p *Postgres) InsertSensors(ctx context.Context, sensors []*types.Sensor) error {
|
||||
|
||||
asset := "pkg/db/sql/psql/insertSensor.sql"
|
||||
asset := fmt.Sprintf("%v/insertSensor.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -361,7 +404,7 @@ func (p *Postgres) InsertSensors(ctx context.Context, sensors []*types.Sensor) e
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectDeviceByID(ctx context.Context, id string) (*types.Device, error) {
|
||||
asset := "pkg/db/sql/psql/selectDeviceByID.sql"
|
||||
asset := fmt.Sprintf("%v/selectDeviceByID.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -387,21 +430,35 @@ func (p *Postgres) SelectDeviceByID(ctx context.Context, id string) (*types.Devi
|
||||
return device, nil
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectMeasuredValuesByIDAndType(ctx context.Context, id string, valueType types.MeasuredValueType) (*types.MeasuredValue, error) {
|
||||
switch valueType {
|
||||
case types.MeasuredValueTypeHumidity:
|
||||
return p.SelectHumidityByID(ctx, id)
|
||||
case types.MeasuredValueTypePressure:
|
||||
return p.SelectPressureByID(ctx, id)
|
||||
case types.MeasuredValueTypeTemperature:
|
||||
return p.SelectTemperatureByID(ctx, id)
|
||||
default:
|
||||
return nil, fmt.Errorf("%v: %v", errorUnknownMeasuredValueType, valueType)
|
||||
func (p *Postgres) SelectInfo(ctx context.Context, key string) (string, error) {
|
||||
asset := fmt.Sprintf("%v/selectInfo.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
stmt, err := p.dbo.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%v: %v", errorPrepareStatement, err)
|
||||
}
|
||||
|
||||
row := stmt.QueryRowContext(ctx, key)
|
||||
if row == nil {
|
||||
return "", errorRowNotFound
|
||||
}
|
||||
|
||||
value := ""
|
||||
err = row.Scan(&value)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%v: %v", errorScanRow, err)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectHumidities(ctx context.Context) ([]*types.MeasuredValue, error) {
|
||||
queryFile := "pkg/db/sql/psql/selectHumidities.sql"
|
||||
queryFile := fmt.Sprintf("%v/selectHumidities.sql", postgresAssetPath)
|
||||
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeHumidity, queryFile, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -410,7 +467,7 @@ func (p *Postgres) SelectHumidities(ctx context.Context) ([]*types.MeasuredValue
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectHumidityByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
||||
queryFile := "pkg/db/sql/psql/selectHumidityByID.sql"
|
||||
queryFile := fmt.Sprintf("%v/selectHumidityByID.sql", postgresAssetPath)
|
||||
args := []interface{}{id}
|
||||
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeHumidity, queryFile, args)
|
||||
if err != nil {
|
||||
@@ -424,8 +481,21 @@ func (p *Postgres) SelectHumidityByID(ctx context.Context, id string) (*types.Me
|
||||
return measuredValues[0], nil
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectMeasuredValuesByIDAndType(ctx context.Context, id string, valueType types.MeasuredValueType) (*types.MeasuredValue, error) {
|
||||
switch valueType {
|
||||
case types.MeasuredValueTypeHumidity:
|
||||
return p.SelectHumidityByID(ctx, id)
|
||||
case types.MeasuredValueTypePressure:
|
||||
return p.SelectPressureByID(ctx, id)
|
||||
case types.MeasuredValueTypeTemperature:
|
||||
return p.SelectTemperatureByID(ctx, id)
|
||||
default:
|
||||
return nil, fmt.Errorf("%v: %v", errorUnknownMeasuredValueType, valueType)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectPressures(ctx context.Context) ([]*types.MeasuredValue, error) {
|
||||
queryFile := "pkg/db/sql/psql/selectPressures.sql"
|
||||
queryFile := fmt.Sprintf("%v/selectPressures.sql", postgresAssetPath)
|
||||
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypePressure, queryFile, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -434,7 +504,7 @@ func (p *Postgres) SelectPressures(ctx context.Context) ([]*types.MeasuredValue,
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectPressureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
||||
queryFile := "pkg/db/sql/psql/selectPressureByID.sql"
|
||||
queryFile := fmt.Sprintf("%v/selectPressureByID.sql", postgresAssetPath)
|
||||
args := []interface{}{id}
|
||||
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypePressure, queryFile, args)
|
||||
if err != nil {
|
||||
@@ -449,7 +519,7 @@ func (p *Postgres) SelectPressureByID(ctx context.Context, id string) (*types.Me
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectSensorByID(ctx context.Context, id string) (*types.Sensor, error) {
|
||||
asset := "pkg/db/sql/psql/selectSensorByID.sql"
|
||||
asset := fmt.Sprintf("%v/selectSensorByID.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
@@ -476,7 +546,7 @@ func (p *Postgres) SelectSensorByID(ctx context.Context, id string) (*types.Sens
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) {
|
||||
queryFile := "pkg/db/sql/psql/selectTemperatures.sql"
|
||||
queryFile := fmt.Sprintf("%v/selectTemperatures.sql", postgresAssetPath)
|
||||
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeTemperature, queryFile, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -485,7 +555,7 @@ func (p *Postgres) SelectTemperatures(ctx context.Context) ([]*types.MeasuredVal
|
||||
}
|
||||
|
||||
func (p *Postgres) SelectTemperatureByID(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
||||
queryFile := "pkg/db/sql/psql/selectTemperatureByID.sql"
|
||||
queryFile := fmt.Sprintf("%v/selectTemperatureByID.sql", postgresAssetPath)
|
||||
args := []interface{}{id}
|
||||
measuredValues, err := p.selectMeasuredValues(ctx, types.MeasuredValueTypeTemperature, queryFile, args)
|
||||
if err != nil {
|
||||
@@ -531,6 +601,28 @@ func (p *Postgres) UpdateDevices(ctx context.Context, devices []*types.Device) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Postgres) UpdateInfo(ctx context.Context, key string, value string) error {
|
||||
asset := fmt.Sprintf("%v/updateInfo.sql", postgresAssetPath)
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorGetAsset, err)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
stmt, err := p.dbo.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorPrepareStatement, err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
_, err = stmt.ExecContext(ctx, key, value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %v", errorStatementExecute, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Postgres) UpdateMeasuredValues(ctx context.Context, measuredValues []*types.MeasuredValue) error {
|
||||
return nil
|
||||
}
|
||||
@@ -538,42 +630,3 @@ func (p *Postgres) UpdateMeasuredValues(ctx context.Context, measuredValues []*t
|
||||
func (p *Postgres) UpdateSensors(ctx context.Context, sensots []*types.Sensor) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func schema(fromVersion *semver.Version, toVersion *semver.Version) error {
|
||||
|
||||
sqlAssetFiles, err := parseAssetDir("pkg/db/sql/psql/schema")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Can not restore sql files: %v", err)
|
||||
}
|
||||
|
||||
for _, sqlAssetFile := range sqlAssetFiles {
|
||||
|
||||
version := strings.Replace()
|
||||
|
||||
sqlSchemaInformations := &schemaInformation{
|
||||
Version: filepath.Split()
|
||||
Asset: sqlAssetFile,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseAssetDir(dir string) ([]string, error) {
|
||||
assetFiles, err := AssetDir(dir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Can not load asset directory %v: %v", dir, err)
|
||||
}
|
||||
|
||||
goldenAssetFiles := assetFiles
|
||||
|
||||
for i, assetFile := range assetFiles {
|
||||
if strings.HasPrefix(assetFile, "/") {
|
||||
// is directory- SKIP
|
||||
goldenAssetFiles = append(goldenAssetFiles[:i], goldenAssetFiles[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return goldenAssetFiles, nil
|
||||
}
|
||||
@@ -2,9 +2,12 @@ package db_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-flucky/flucky/pkg/db"
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/go-flucky/flucky/pkg/config"
|
||||
"github.com/go-flucky/flucky/pkg/storage/db"
|
||||
"github.com/go-flucky/flucky/pkg/types"
|
||||
"github.com/go-flucky/flucky/test/goldenfiles"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -19,11 +22,15 @@ var (
|
||||
database db.Database
|
||||
|
||||
postgresContainerImage string = "docker.io/postgres/postgres"
|
||||
postgresHost string = "localhost"
|
||||
postgresPort string = "5432"
|
||||
postgresUser string = "postgres"
|
||||
postgresPassword string = "postgres"
|
||||
postgresDatabase string = "postgres"
|
||||
|
||||
postgresSettings = &config.DatabaseSettings{
|
||||
Vendor: config.VendorPostgreSQL,
|
||||
Host: "localhost",
|
||||
Port: "5432",
|
||||
User: "postgres",
|
||||
Password: "postgres",
|
||||
Database: "postgres",
|
||||
}
|
||||
|
||||
goldenDevicesFilePath string = "test/goldenfiles/json/goldenDevices.json"
|
||||
goldenSensorsFilePath string = "test/goldenfiles/json/goldenSensors.json"
|
||||
@@ -74,7 +81,7 @@ func TestPostgres(t *testing.T) {
|
||||
|
||||
load(t)
|
||||
|
||||
db, err := db.New(db.DBOTypePostgres, postgresHost, postgresPort, postgresDatabase, postgresUser, postgresPassword)
|
||||
db, err := db.New(postgresSettings)
|
||||
database = db
|
||||
require.Nil(err)
|
||||
|
||||
@@ -83,54 +90,54 @@ func TestPostgres(t *testing.T) {
|
||||
Name: "schema",
|
||||
Test: testSchemaCreate,
|
||||
},
|
||||
// &test{
|
||||
// Name: "insertDevices",
|
||||
// Test: testInsertDevices,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "insertSensors",
|
||||
// Test: testInsertSensors,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "insertHumidity",
|
||||
// Test: testInsertHumidity,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "insertPressure",
|
||||
// Test: testInsertPressure,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "insertTemperatures",
|
||||
// Test: testInsertTemperatures,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "deleteHumidities",
|
||||
// Test: testDeleteHumidity,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "deletePressures",
|
||||
// Test: testDeletePressures,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "deleteTemperatures",
|
||||
// Test: testDeleteTemperatures,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "insertMeasuredValues",
|
||||
// Test: testInsertMeasuredValues,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "deleteMeasuredValues",
|
||||
// Test: testDeleteMeasuredValues,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "deleteSensors",
|
||||
// Test: testDeleteSensors,
|
||||
// },
|
||||
// &test{
|
||||
// Name: "deleteDevices",
|
||||
// Test: testDeleteDevices,
|
||||
// },
|
||||
&test{
|
||||
Name: "insertDevices",
|
||||
Test: testInsertDevices,
|
||||
},
|
||||
&test{
|
||||
Name: "insertSensors",
|
||||
Test: testInsertSensors,
|
||||
},
|
||||
&test{
|
||||
Name: "insertHumidity",
|
||||
Test: testInsertHumidity,
|
||||
},
|
||||
&test{
|
||||
Name: "insertPressure",
|
||||
Test: testInsertPressure,
|
||||
},
|
||||
&test{
|
||||
Name: "insertTemperatures",
|
||||
Test: testInsertTemperatures,
|
||||
},
|
||||
&test{
|
||||
Name: "deleteHumidities",
|
||||
Test: testDeleteHumidity,
|
||||
},
|
||||
&test{
|
||||
Name: "deletePressures",
|
||||
Test: testDeletePressures,
|
||||
},
|
||||
&test{
|
||||
Name: "deleteTemperatures",
|
||||
Test: testDeleteTemperatures,
|
||||
},
|
||||
&test{
|
||||
Name: "insertMeasuredValues",
|
||||
Test: testInsertMeasuredValues,
|
||||
},
|
||||
&test{
|
||||
Name: "deleteMeasuredValues",
|
||||
Test: testDeleteMeasuredValues,
|
||||
},
|
||||
&test{
|
||||
Name: "deleteSensors",
|
||||
Test: testDeleteSensors,
|
||||
},
|
||||
&test{
|
||||
Name: "deleteDevices",
|
||||
Test: testDeleteDevices,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@@ -140,9 +147,18 @@ func TestPostgres(t *testing.T) {
|
||||
|
||||
func testSchemaCreate(t *testing.T) {
|
||||
require := require.New(t)
|
||||
ctx := context.Background()
|
||||
err := database.Schema(ctx, "v0.1.0")
|
||||
|
||||
homePath := "pkg/storage/db/sql/psql/schema"
|
||||
sqlAssetFiles, err := db.AssetDir(homePath)
|
||||
require.NoError(err)
|
||||
|
||||
ctx := context.Background()
|
||||
for _, sqlAssetFile := range sqlAssetFiles {
|
||||
fromVersion, err := semver.NewVersion(strings.ReplaceAll(sqlAssetFile, ".sql", ""))
|
||||
require.NoError(err)
|
||||
err = database.Schema(ctx, fromVersion)
|
||||
require.NoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testInsertDevices(t *testing.T) {
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,2 @@
|
||||
INSERT INTO info (key, value)
|
||||
VALUES ($1, $2);
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,3 @@
|
||||
SELECT value
|
||||
FROM info
|
||||
WHERE key = $1;
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,3 @@
|
||||
UPDATE info
|
||||
SET value = $2
|
||||
WHERE key = $1;
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -8,6 +8,5 @@ type Device struct {
|
||||
DeviceName string `json:"device_name" xml:"device_name"`
|
||||
DeviceLocation *string `json:"device_location" xml:"device_location"`
|
||||
DeviceLastContact *time.Time `json:"device_last_contact" xml:"device_last_contact"`
|
||||
Logfile string `json:"logfile" xml:"logfile"`
|
||||
CreationDate time.Time `json:"creation_date" xml:"creation_date"`
|
||||
}
|
||||
Reference in new issue
Block a user