fix: add postgres backend
changes: - Add postgres backend - Modified or added table attributes. UpdateDate, ForeignKeys, Booleans - Fix test for sqlite and postgres. Compare json instead the struct.
This commit is contained in:
parent
a1c28a0a2e
commit
4931c63c10
1
Makefile
1
Makefile
@ -159,6 +159,7 @@ container-run:
|
||||
${CONTAINER_RUNTIME} run \
|
||||
--rm \
|
||||
--volume ${PWD}:/workspace \
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
docker.io/volkerraschek/build-image:latest \
|
||||
make ${COMMAND} \
|
||||
GOPROXY=${GOPROXY} \
|
||||
|
8
go.mod
8
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/volker-raschek/flucky
|
||||
|
||||
go 1.12
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
@ -12,11 +12,11 @@ require (
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/go-flucky/go-dht v0.1.1
|
||||
github.com/lib/pq v1.4.0
|
||||
github.com/mattn/go-sqlite3 v1.10.0
|
||||
github.com/lib/pq v1.6.0
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/stretchr/testify v1.6.0
|
||||
github.com/volker-raschek/go-logger v0.1.0
|
||||
)
|
||||
|
40
go.sum
40
go.sum
@ -5,6 +5,8 @@ github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF0
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 h1:P5U+E4x5OkVEKQDklVPmzs71WM56RTTRqV4OrDC//Y4=
|
||||
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
@ -56,13 +58,29 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
|
||||
github.com/jcmturner/gokrb5/v8 v8.2.0 h1:lzPl/30ZLkTveYsYZPKMcgXc8MbnE6RsTd4F9KgiLtk=
|
||||
github.com/jcmturner/gokrb5/v8 v8.2.0/go.mod h1:T1hnNppQsBtxW0tCHMHTkAt8n/sABdzZgZdoFrZaZNM=
|
||||
github.com/jcmturner/rpc/v2 v2.0.2 h1:gMB4IwRXYsWw4Bc6o/az2HJgFUA1ffSh90i26ZJ6Xl0=
|
||||
github.com/jcmturner/rpc/v2 v2.0.2/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
@ -76,9 +94,14 @@ 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.4.0 h1:TmtCFbH+Aw0AixwyttznSMQDgbR5Yed/Gg6S8Funrhc=
|
||||
github.com/lib/pq v1.4.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.6.0 h1:I5DPxhYJChW9KYc66se+oKFFQX6VuQrKiprsX6ivRZc=
|
||||
github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.13.0 h1:LnJI81JidiW9r7pS/hXe6cFeO5EXNq7KbfvoJLRI69c=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
@ -122,6 +145,7 @@ github.com/stianeikeland/go-rpio v4.2.0+incompatible h1:CUOlIxdJdT+H1obJPsmg8byu
|
||||
github.com/stianeikeland/go-rpio v4.2.0+incompatible/go.mod h1:Sh81rdJwD96E2wja2Gd7rrKM+XZ9LrwvN2w4IXrqLR8=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -129,6 +153,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho=
|
||||
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/volker-raschek/go-logger v0.1.0 h1:BJPK4wCfcWlQYnOQC7ORU4LlMSgEYcwvpXQFs2rdPhE=
|
||||
@ -141,14 +167,20 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA=
|
||||
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -158,6 +190,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -171,11 +204,18 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
periph.io/x/periph v3.4.0+incompatible h1:5gzxE4ryPq52cdqSw0mErR6pyJK8cBF2qdUAcOWh0bo=
|
||||
periph.io/x/periph v3.4.0+incompatible/go.mod h1:EWr+FCIU2dBWz5/wSWeiIUJTriYv9v2j2ENBmgYyy7Y=
|
||||
|
@ -52,6 +52,7 @@ func New(dsnURL *url.URL, flogger logger.Logger) (Database, error) {
|
||||
// Load Queryfiles
|
||||
queries := make(map[string]string, 0)
|
||||
for _, asset := range AssetNames() {
|
||||
|
||||
if !strings.Contains(asset, dsnURL.Scheme) {
|
||||
continue
|
||||
}
|
||||
@ -72,17 +73,19 @@ func New(dsnURL *url.URL, flogger logger.Logger) (Database, error) {
|
||||
)
|
||||
|
||||
switch dsnURL.Scheme {
|
||||
// case "postgres":
|
||||
// // postgres://[user]:[password]@[host]:[port]/[path]?[query]
|
||||
// newDBO, err := sql.Open(storageEndpoint.Scheme, storageEndpoint.String())
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
case "postgres":
|
||||
|
||||
// return &Postgres{
|
||||
// dbo: newDBO,
|
||||
// flogger: flogger,
|
||||
// }, nil
|
||||
// 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":
|
||||
|
||||
|
@ -4,32 +4,27 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
|
||||
"github.com/volker-raschek/flucky/pkg/types"
|
||||
"github.com/volker-raschek/go-logger/pkg/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
postgresAssetPath = "pkg/storage/postgres"
|
||||
)
|
||||
|
||||
// Postgres implementation
|
||||
type Postgres struct {
|
||||
dbo *sql.DB
|
||||
flogger logger.Logger
|
||||
queries map[string]string
|
||||
}
|
||||
|
||||
// DeleteDevices from the database
|
||||
func (postgres *Postgres) DeleteDevices(ctx context.Context, deviceIDs ...string) error {
|
||||
asset := filepath.Join(postgresAssetPath, "deleteDevice.sql")
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
queryFile := "deleteDevice.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
|
||||
if err != nil {
|
||||
@ -55,12 +50,11 @@ func (postgres *Postgres) DeleteDevices(ctx context.Context, deviceIDs ...string
|
||||
|
||||
// DeleteSensors from the database
|
||||
func (postgres *Postgres) DeleteSensors(ctx context.Context, sensorIDs ...string) error {
|
||||
asset := filepath.Join(postgresAssetPath, "deleteSensor.sql")
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
queryFile := "deleteSensor.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
|
||||
if err != nil {
|
||||
@ -86,12 +80,11 @@ func (postgres *Postgres) DeleteSensors(ctx context.Context, sensorIDs ...string
|
||||
|
||||
// InsertDevices into the database
|
||||
func (postgres *Postgres) InsertDevices(ctx context.Context, devices ...*types.Device) error {
|
||||
asset := filepath.Join(postgresAssetPath, "insertDevice.sql")
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
queryFile := "insertDevice.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
|
||||
if err != nil {
|
||||
@ -105,7 +98,7 @@ func (postgres *Postgres) InsertDevices(ctx context.Context, devices ...*types.D
|
||||
defer stmt.Close()
|
||||
|
||||
for _, device := range devices {
|
||||
_, err = stmt.Exec(&device.ID, &device.Name, &device.Location, &device.CreationDate)
|
||||
_, err = stmt.Exec(&device.ID, &device.Name, &device.Location, &device.CreationDate, &device.UpdateDate)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("Failed to execute statement: %v", err)
|
||||
@ -132,12 +125,11 @@ func (postgres *Postgres) InsertMeasuredValues(ctx context.Context, measuredValu
|
||||
}
|
||||
|
||||
// General insert function
|
||||
insert := func(tx *sql.Tx, asset string, measuredValues []*types.MeasuredValue) error {
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
insert := func(tx *sql.Tx, queryFile string, measuredValues []*types.MeasuredValue) error {
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
stmt, err := tx.Prepare(query)
|
||||
if err != nil {
|
||||
@ -146,7 +138,15 @@ func (postgres *Postgres) InsertMeasuredValues(ctx context.Context, measuredValu
|
||||
defer stmt.Close()
|
||||
|
||||
for _, measuredValue := range measuredValues {
|
||||
_, err := stmt.Exec(&measuredValue.ID, &measuredValue.Value, &measuredValue.SensorID, &measuredValue.CreationDate)
|
||||
_, 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)
|
||||
}
|
||||
@ -156,21 +156,21 @@ func (postgres *Postgres) InsertMeasuredValues(ctx context.Context, measuredValu
|
||||
}
|
||||
|
||||
for measuredValueType, measuredValues := range splittedMeasuredValues {
|
||||
var asset string
|
||||
var queryFile string
|
||||
|
||||
switch measuredValueType {
|
||||
case "humidity":
|
||||
asset = filepath.Join(postgresAssetPath, "insertHumidity.sql")
|
||||
queryFile = "insertHumidity.sql"
|
||||
case "pressure":
|
||||
asset = filepath.Join(postgresAssetPath, "insertPressure.sql")
|
||||
queryFile = "insertPressure.sql"
|
||||
case "temperature":
|
||||
asset = filepath.Join(postgresAssetPath, "insertTemperature.sql")
|
||||
queryFile = "insertTemperature.sql"
|
||||
default:
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("Measured value type %v not supported", measuredValueType)
|
||||
}
|
||||
|
||||
err := insert(tx, asset, measuredValues)
|
||||
err := insert(tx, queryFile, measuredValues)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
@ -182,12 +182,11 @@ func (postgres *Postgres) InsertMeasuredValues(ctx context.Context, measuredValu
|
||||
|
||||
// InsertSensors into the database
|
||||
func (postgres *Postgres) InsertSensors(ctx context.Context, sensors ...*types.Sensor) error {
|
||||
asset := filepath.Join(postgresAssetPath, "insertSensor.sql")
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
queryFile := "insertSensor.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
|
||||
if err != nil {
|
||||
@ -201,7 +200,21 @@ func (postgres *Postgres) InsertSensors(ctx context.Context, sensors ...*types.S
|
||||
defer stmt.Close()
|
||||
|
||||
for _, sensor := range sensors {
|
||||
_, err = stmt.Exec(&sensor.ID, &sensor.Name, &sensor.Location, &sensor.WireID, &sensor.I2CBus, &sensor.I2CAddress, &sensor.GPIONumber, &sensor.Model, &sensor.Enabled, &sensor.DeviceID, &sensor.CreationDate)
|
||||
_, err = stmt.Exec(
|
||||
&sensor.ID,
|
||||
&sensor.Name,
|
||||
&sensor.Location,
|
||||
&sensor.WireID,
|
||||
&sensor.I2CBus,
|
||||
&sensor.I2CAddress,
|
||||
&sensor.GPIONumber,
|
||||
&sensor.Model,
|
||||
&sensor.Enabled,
|
||||
&sensor.TickDuration,
|
||||
&sensor.DeviceID,
|
||||
&sensor.CreationDate,
|
||||
&sensor.UpdateDate,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("Failed to execute statement: %v", err)
|
||||
@ -211,75 +224,69 @@ func (postgres *Postgres) InsertSensors(ctx context.Context, sensors ...*types.S
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// Scheme creates all required tables if not exist
|
||||
func (postgres *Postgres) Scheme(ctx context.Context) error {
|
||||
for _, query := range []string{
|
||||
postgres.queries["createTableDevices.sql"],
|
||||
postgres.queries["createTableSensors.sql"],
|
||||
postgres.queries["createTableHumidites.sql"],
|
||||
postgres.queries["createTablePressures.sql"],
|
||||
postgres.queries["createTableTemperatures.sql"],
|
||||
} {
|
||||
_, err := postgres.dbo.ExecContext(ctx, query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectDevice from database
|
||||
func (postgres *Postgres) SelectDevice(ctx context.Context, id string) (*types.Device, error) {
|
||||
asset := filepath.Join(postgresAssetPath, "selectDevice.sql")
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
queryFile := "selectDevice.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(query)
|
||||
devices, err := postgres.selectDevices(tx, query, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to prepare statement: %v", err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
row := stmt.QueryRow(id)
|
||||
|
||||
device := new(types.Device)
|
||||
err = row.Scan(&device.ID, &device.Name, &device.Location, &device.CreationDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan row: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to commit transaction: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return device, nil
|
||||
if len(devices) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return devices[0], nil
|
||||
}
|
||||
|
||||
// SelectDevices from the database
|
||||
func (postgres *Postgres) SelectDevices(ctx context.Context) ([]*types.Device, error) {
|
||||
asset := filepath.Join(postgresAssetPath, "selectDevices.sql")
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
queryFile := "selectDevices.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(query)
|
||||
devices, err := postgres.selectDevices(tx, query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to prepare statement: %v", err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to query statement: %v", err)
|
||||
}
|
||||
|
||||
devices := make([]*types.Device, 0)
|
||||
for rows.Next() {
|
||||
device := new(types.Device)
|
||||
err = rows.Scan(&device.ID, &device.Name, &device.Location, &device.CreationDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan row: %v", err)
|
||||
}
|
||||
devices = append(devices, device)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
@ -290,32 +297,218 @@ func (postgres *Postgres) SelectDevices(ctx context.Context) ([]*types.Device, e
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
// SelectSensor from database
|
||||
func (postgres *Postgres) SelectSensor(ctx context.Context, id string) (*types.Sensor, error) {
|
||||
asset := filepath.Join(postgresAssetPath, "selectSensor.sql")
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
|
||||
}
|
||||
|
||||
func (postgres *Postgres) selectDevices(tx *sql.Tx, query string, args ...interface{}) ([]*types.Device, error) {
|
||||
stmt, err := tx.Prepare(query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to prepare statement: %v", err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
row := stmt.QueryRow(id)
|
||||
|
||||
sensor := new(types.Sensor)
|
||||
err = row.Scan(&sensor.ID, &sensor.Name, &sensor.Location, &sensor.WireID, &sensor.I2CBus, &sensor.I2CAddress, &sensor.GPIONumber, &sensor.Model, &sensor.Enabled, &sensor.DeviceID, &sensor.CreationDate)
|
||||
rows, err := stmt.Query(args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan row: %v", err)
|
||||
return nil, fmt.Errorf("Failed to query statement: %v", err)
|
||||
}
|
||||
|
||||
devices := make([]*types.Device, 0)
|
||||
for rows.Next() {
|
||||
device := new(types.Device)
|
||||
err = rows.Scan(
|
||||
&device.ID,
|
||||
&device.Name,
|
||||
&device.Location,
|
||||
&device.CreationDate,
|
||||
&device.UpdateDate,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan row: %v", err)
|
||||
}
|
||||
devices = append(devices, device)
|
||||
}
|
||||
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
// SelectHumidity returns humidity from the database
|
||||
func (postgres *Postgres) SelectHumidity(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
||||
queryFile := "selectHumidity.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
measuredValues, err := postgres.selectMeasuredValue(tx, query, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if measuredValues == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, measuredValue := range measuredValues {
|
||||
measuredValue.ValueType = "humidity"
|
||||
}
|
||||
|
||||
return measuredValues[0], nil
|
||||
}
|
||||
|
||||
// SelectHumidities returns humidities from the database
|
||||
func (postgres *Postgres) SelectHumidities(ctx context.Context) ([]*types.MeasuredValue, error) {
|
||||
queryFile := "selectHumidities.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
measuredValues, err := postgres.selectMeasuredValue(tx, query, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, measuredValue := range measuredValues {
|
||||
measuredValue.ValueType = "humidity"
|
||||
}
|
||||
|
||||
return measuredValues, nil
|
||||
}
|
||||
|
||||
func (postgres *Postgres) selectMeasuredValue(tx *sql.Tx, query string, args ...interface{}) ([]*types.MeasuredValue, error) {
|
||||
stmt, err := tx.Prepare(query)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query(args...)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
measuredValues := make([]*types.MeasuredValue, 0)
|
||||
for rows.Next() {
|
||||
measuredValue := new(types.MeasuredValue)
|
||||
err := rows.Scan(
|
||||
&measuredValue.ID,
|
||||
&measuredValue.Value,
|
||||
&measuredValue.SensorID,
|
||||
&measuredValue.Date,
|
||||
&measuredValue.CreationDate,
|
||||
&measuredValue.UpdateDate,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
measuredValues = append(measuredValues, measuredValue)
|
||||
}
|
||||
|
||||
return measuredValues, nil
|
||||
}
|
||||
|
||||
// SelectPressure returns pressure from the database
|
||||
func (postgres *Postgres) SelectPressure(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
||||
queryFile := "selectPressure.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
measuredValues, err := postgres.selectMeasuredValue(tx, query, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if measuredValues == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, measuredValue := range measuredValues {
|
||||
measuredValue.ValueType = "pressure"
|
||||
}
|
||||
|
||||
return measuredValues[0], nil
|
||||
}
|
||||
|
||||
// SelectPressures returns pressure from the database
|
||||
func (postgres *Postgres) SelectPressures(ctx context.Context) ([]*types.MeasuredValue, error) {
|
||||
queryFile := "selectPressures.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
measuredValues, err := postgres.selectMeasuredValue(tx, query, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, measuredValue := range measuredValues {
|
||||
measuredValue.ValueType = "pressure"
|
||||
}
|
||||
|
||||
return measuredValues, nil
|
||||
}
|
||||
|
||||
// SelectSensor from database
|
||||
func (postgres *Postgres) SelectSensor(ctx context.Context, id string) (*types.Sensor, error) {
|
||||
queryFile := "selectSensor.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
|
||||
}
|
||||
|
||||
sensors, err := postgres.selectSensors(tx, query, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
@ -323,42 +516,29 @@ func (postgres *Postgres) SelectSensor(ctx context.Context, id string) (*types.S
|
||||
return nil, fmt.Errorf("Failed to commit transaction: %v", err)
|
||||
}
|
||||
|
||||
return sensor, nil
|
||||
if len(sensors) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return sensors[0], nil
|
||||
}
|
||||
|
||||
// SelectSensors from the database
|
||||
func (postgres *Postgres) SelectSensors(ctx context.Context) ([]*types.Sensor, error) {
|
||||
asset := filepath.Join(postgresAssetPath, "selectSensors.sql")
|
||||
queryBytes, err := Asset(asset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to load asset %v: %v", asset, err)
|
||||
queryFile := "selectSensors.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
query := string(queryBytes)
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to begin new transaction: %v", err)
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(query)
|
||||
sensors, err := postgres.selectSensors(tx, query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to prepare statement: %v", err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to query statement: %v", err)
|
||||
}
|
||||
|
||||
sensors := make([]*types.Sensor, 0)
|
||||
for rows.Next() {
|
||||
sensor := new(types.Sensor)
|
||||
err = rows.Scan(&sensor.ID, &sensor.Name, &sensor.Location, &sensor.WireID, &sensor.I2CBus, &sensor.I2CAddress, &sensor.GPIONumber, &sensor.Model, &sensor.Enabled, &sensor.DeviceID, &sensor.CreationDate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan row: %v", err)
|
||||
}
|
||||
sensors = append(sensors, sensor)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
@ -369,12 +549,193 @@ func (postgres *Postgres) SelectSensors(ctx context.Context) ([]*types.Sensor, e
|
||||
return sensors, nil
|
||||
}
|
||||
|
||||
func (postgres *Postgres) selectSensors(tx *sql.Tx, query string, args ...interface{}) ([]*types.Sensor, error) {
|
||||
stmt, err := tx.Prepare(query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to prepare statement: %v", err)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query(args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to query statement: %v", err)
|
||||
}
|
||||
|
||||
sensors := make([]*types.Sensor, 0)
|
||||
for rows.Next() {
|
||||
sensor := new(types.Sensor)
|
||||
err = rows.Scan(
|
||||
&sensor.ID,
|
||||
&sensor.Name,
|
||||
&sensor.Location,
|
||||
&sensor.WireID,
|
||||
&sensor.I2CBus,
|
||||
&sensor.I2CAddress,
|
||||
&sensor.GPIONumber,
|
||||
&sensor.Model,
|
||||
&sensor.Enabled,
|
||||
&sensor.TickDuration,
|
||||
&sensor.DeviceID,
|
||||
&sensor.CreationDate,
|
||||
&sensor.UpdateDate,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan row: %v", err)
|
||||
}
|
||||
sensors = append(sensors, sensor)
|
||||
}
|
||||
|
||||
return sensors, nil
|
||||
}
|
||||
|
||||
// SelectTemperature returns temperatures from the database
|
||||
func (postgres *Postgres) SelectTemperature(ctx context.Context, id string) (*types.MeasuredValue, error) {
|
||||
queryFile := "selectTemperature.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
measuredValues, err := postgres.selectMeasuredValue(tx, query, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if measuredValues == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, measuredValue := range measuredValues {
|
||||
measuredValue.ValueType = "temperatures"
|
||||
}
|
||||
|
||||
return measuredValues[0], nil
|
||||
}
|
||||
|
||||
// SelectTemperatures returns temperatures from the database
|
||||
func (postgres *Postgres) SelectTemperatures(ctx context.Context) ([]*types.MeasuredValue, error) {
|
||||
queryFile := "selectTemperatures.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return nil, fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
measuredValues, err := postgres.selectMeasuredValue(tx, query, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, measuredValue := range measuredValues {
|
||||
measuredValue.ValueType = "temperatures"
|
||||
}
|
||||
|
||||
return measuredValues, nil
|
||||
}
|
||||
|
||||
// UpdateDevices updates a device in the database
|
||||
func (postgres *Postgres) UpdateDevices(ctx context.Context, devices ...*types.Device) error {
|
||||
return nil
|
||||
queryFile := "updateDevice.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(query)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for _, device := range devices {
|
||||
now := time.Now()
|
||||
device.UpdateDate = &now
|
||||
|
||||
_, err := stmt.Exec(
|
||||
&device.Name,
|
||||
&device.Location,
|
||||
&device.CreationDate,
|
||||
&device.UpdateDate,
|
||||
&device.ID,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// UpdateSensors updates a sensor in the database
|
||||
func (postgres *Postgres) UpdateSensors(ctx context.Context, sensor ...*types.Sensor) error {
|
||||
return nil
|
||||
func (postgres *Postgres) UpdateSensors(ctx context.Context, sensors ...*types.Sensor) error {
|
||||
queryFile := "updateSensor.sql"
|
||||
query, present := postgres.queries[queryFile]
|
||||
if !present {
|
||||
return fmt.Errorf("SQLite-Backend: File %v not found", queryFile)
|
||||
}
|
||||
|
||||
tx, err := postgres.dbo.BeginTx(ctx, &sql.TxOptions{ReadOnly: false})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(query)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for _, sensor := range sensors {
|
||||
now := time.Now()
|
||||
sensor.UpdateDate = &now
|
||||
_, err := stmt.Exec(
|
||||
&sensor.Name,
|
||||
&sensor.Location,
|
||||
&sensor.WireID,
|
||||
&sensor.I2CBus,
|
||||
&sensor.I2CAddress,
|
||||
&sensor.GPIONumber,
|
||||
&sensor.Model,
|
||||
&sensor.Enabled,
|
||||
&sensor.TickDuration,
|
||||
&sensor.DeviceID,
|
||||
&sensor.CreationDate,
|
||||
&sensor.UpdateDate,
|
||||
&sensor.ID,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
7
pkg/repository/db/postgres/createTableDevices.sql
Normal file
7
pkg/repository/db/postgres/createTableDevices.sql
Normal file
@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS devices (
|
||||
device_id CHAR(36) CONSTRAINT pk_devices PRIMARY KEY,
|
||||
device_name VARCHAR(64) NOT NULL,
|
||||
device_location VARCHAR(64),
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP
|
||||
);
|
14
pkg/repository/db/postgres/createTableHumidities.sql
Normal file
14
pkg/repository/db/postgres/createTableHumidities.sql
Normal file
@ -0,0 +1,14 @@
|
||||
CREATE TABLE IF NOT EXISTS humidities (
|
||||
id CHAR(36) CONSTRAINT pk_humidities PRIMARY KEY,
|
||||
value NUMERIC(10,3) NOT NULL,
|
||||
date TIMESTAMP NOT NULL,
|
||||
sensor_id CHAR(36) NOT NULL,
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE humidities
|
||||
ADD FOREIGN KEY (sensor_id)
|
||||
REFERENCES sensors(sensor_id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
14
pkg/repository/db/postgres/createTablePressures.sql
Normal file
14
pkg/repository/db/postgres/createTablePressures.sql
Normal file
@ -0,0 +1,14 @@
|
||||
CREATE TABLE IF NOT EXISTS pressures (
|
||||
id CHAR(36) CONSTRAINT pk_pressures PRIMARY KEY,
|
||||
value NUMERIC(10,3) NOT NULL,
|
||||
date TIMESTAMP NOT NULL,
|
||||
sensor_id CHAR(36) NOT NULL,
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE pressures
|
||||
ADD FOREIGN KEY (sensor_id)
|
||||
REFERENCES sensors(sensor_id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
21
pkg/repository/db/postgres/createTableSensors.sql
Normal file
21
pkg/repository/db/postgres/createTableSensors.sql
Normal file
@ -0,0 +1,21 @@
|
||||
CREATE TABLE IF NOT EXISTS sensors (
|
||||
sensor_id CHAR(36) CONSTRAINT pk_sensors PRIMARY KEY,
|
||||
sensor_name VARCHAR(64) NOT NULL,
|
||||
sensor_location VARCHAR(64),
|
||||
wire_id VARCHAR(64),
|
||||
i2c_bus VARCHAR(255),
|
||||
i2c_address VARCHAR(12),
|
||||
gpio_number VARCHAR(6),
|
||||
sensor_model VARCHAR(16) NOT NULL,
|
||||
sensor_enabled BOOLEAN DEFAULT TRUE NOT NULL,
|
||||
tick_duration VARCHAR(6) NOT NULL,
|
||||
device_id CHAR(36) NOT NULL,
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE sensors
|
||||
ADD FOREIGN KEY (device_id)
|
||||
REFERENCES devices(device_id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
14
pkg/repository/db/postgres/createTableTemperatures.sql
Normal file
14
pkg/repository/db/postgres/createTableTemperatures.sql
Normal file
@ -0,0 +1,14 @@
|
||||
CREATE TABLE IF NOT EXISTS temperatures (
|
||||
id CHAR(36) CONSTRAINT pk_temperatures PRIMARY KEY,
|
||||
value NUMERIC(10,3) NOT NULL,
|
||||
date TIMESTAMP NOT NULL,
|
||||
sensor_id CHAR(36) NOT NULL,
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE temperatures
|
||||
ADD FOREIGN KEY (sensor_id)
|
||||
REFERENCES sensors(sensor_id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE;
|
@ -1,2 +1,2 @@
|
||||
DELETE FROM sensors
|
||||
DELETE FROM devices
|
||||
WHERE device_id = $1;
|
@ -2,6 +2,7 @@ INSERT INTO devices (
|
||||
device_id,
|
||||
device_name,
|
||||
device_location,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
)
|
||||
VALUES ($1, $2, $3, $4);
|
||||
VALUES ($1, $2, $3, $4, $5);
|
@ -1,10 +1,9 @@
|
||||
INSERT INTO humidities (
|
||||
humidity_id,
|
||||
humidity_value,
|
||||
humidity_from_date,
|
||||
humidity_till_date,
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7);
|
||||
VALUES ($1, $2, $3, $4, $5, $6);
|
@ -1,10 +1,9 @@
|
||||
INSERT INTO pressures (
|
||||
pressure_id,
|
||||
pressure_value,
|
||||
pressure_from_date,
|
||||
pressure_till_date,
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7);
|
||||
VALUES ($1, $2, $3, $4, $5, $6);
|
@ -8,7 +8,9 @@ INSERT INTO sensors (
|
||||
gpio_number,
|
||||
sensor_model,
|
||||
sensor_enabled,
|
||||
tick_duration,
|
||||
device_id,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);
|
@ -1,10 +1,9 @@
|
||||
INSERT INTO temperatures (
|
||||
temperature_id,
|
||||
temperature_value,
|
||||
temperature_from_date,
|
||||
temperature_till_date,
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7);
|
||||
VALUES ($1, $2, $3, $4, $5, $6);
|
@ -2,7 +2,8 @@ SELECT
|
||||
device_id,
|
||||
device_name,
|
||||
device_location,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
devices
|
||||
WHERE device_id = $1;
|
@ -2,6 +2,9 @@ SELECT
|
||||
device_id,
|
||||
device_name,
|
||||
device_location,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
devices;
|
||||
devices
|
||||
ORDER BY
|
||||
device_id ASC;
|
9
pkg/repository/db/postgres/selectHumidities.sql
Normal file
9
pkg/repository/db/postgres/selectHumidities.sql
Normal file
@ -0,0 +1,9 @@
|
||||
SELECT
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
humidities;
|
11
pkg/repository/db/postgres/selectHumidity.sql
Normal file
11
pkg/repository/db/postgres/selectHumidity.sql
Normal file
@ -0,0 +1,11 @@
|
||||
SELECT
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
humidities
|
||||
WHERE
|
||||
humidity_id = $1
|
11
pkg/repository/db/postgres/selectPressure.sql
Normal file
11
pkg/repository/db/postgres/selectPressure.sql
Normal file
@ -0,0 +1,11 @@
|
||||
SELECT
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
pressures
|
||||
WHERE
|
||||
pressure_id = $1
|
9
pkg/repository/db/postgres/selectPressures.sql
Normal file
9
pkg/repository/db/postgres/selectPressures.sql
Normal file
@ -0,0 +1,9 @@
|
||||
SELECT
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
pressures;
|
@ -8,8 +8,10 @@ SELECT
|
||||
gpio_number,
|
||||
sensor_model,
|
||||
sensor_enabled,
|
||||
tick_duration,
|
||||
device_id,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
sensors
|
||||
WHERE
|
||||
|
@ -8,7 +8,11 @@ SELECT
|
||||
gpio_number,
|
||||
sensor_model,
|
||||
sensor_enabled,
|
||||
tick_duration,
|
||||
device_id,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
sensors;
|
||||
sensors
|
||||
ORDER BY
|
||||
sensor_id ASC;
|
11
pkg/repository/db/postgres/selectTemperature.sql
Normal file
11
pkg/repository/db/postgres/selectTemperature.sql
Normal file
@ -0,0 +1,11 @@
|
||||
SELECT
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
temperatures
|
||||
WHERE
|
||||
temperature_id = $1
|
9
pkg/repository/db/postgres/selectTemperatures.sql
Normal file
9
pkg/repository/db/postgres/selectTemperatures.sql
Normal file
@ -0,0 +1,9 @@
|
||||
SELECT
|
||||
id,
|
||||
value,
|
||||
date,
|
||||
sensor_id,
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
temperatures
|
@ -1,8 +1,8 @@
|
||||
UPDATE device
|
||||
UPDATE devices
|
||||
SET
|
||||
device_id = $1,
|
||||
device_name = $2,
|
||||
device_location = $3,
|
||||
creation_date = $4
|
||||
device_name = $1,
|
||||
device_location = $2,
|
||||
creation_date = $3,
|
||||
update_date = $4
|
||||
WHERE
|
||||
device_id = $5,
|
||||
device_id = $5
|
@ -1,15 +1,16 @@
|
||||
UPDATE sensors
|
||||
SET
|
||||
sensor_id = $1,
|
||||
sensor_name = $2,
|
||||
sensor_location = $3,
|
||||
wire_id = $4,
|
||||
i2c_bus = $5,
|
||||
i2c_address = $6,
|
||||
gpio_number = $7,
|
||||
sensor_model = $8,
|
||||
sensor_enabled = $9,
|
||||
sensor_name = $1,
|
||||
sensor_location = $2,
|
||||
wire_id = $3,
|
||||
i2c_bus = $4,
|
||||
i2c_address = $5,
|
||||
gpio_number = $6,
|
||||
sensor_model = $7,
|
||||
sensor_enabled = $8,
|
||||
tick_duration = $9,
|
||||
device_id = $10,
|
||||
creation_date = $11
|
||||
creation_date = $11,
|
||||
update_date = $12
|
||||
WHERE
|
||||
sensor_id = $12;
|
||||
sensor_id = $13;
|
@ -97,7 +97,7 @@ func (sqlite *SQLite) InsertDevices(ctx context.Context, devices ...*types.Devic
|
||||
defer stmt.Close()
|
||||
|
||||
for _, device := range devices {
|
||||
_, err = stmt.Exec(&device.ID, &device.Name, &device.Location, &device.CreationDate)
|
||||
_, err = stmt.Exec(&device.ID, &device.Name, &device.Location, &device.CreationDate, &device.UpdateDate)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("Failed to execute statement: %v", err)
|
||||
@ -140,8 +140,8 @@ func (sqlite *SQLite) InsertMeasuredValues(ctx context.Context, measuredValues .
|
||||
_, err := stmt.Exec(
|
||||
&measuredValue.ID,
|
||||
&measuredValue.Value,
|
||||
&measuredValue.SensorID,
|
||||
&measuredValue.Date,
|
||||
&measuredValue.SensorID,
|
||||
&measuredValue.CreationDate,
|
||||
&measuredValue.UpdateDate,
|
||||
)
|
||||
@ -212,6 +212,7 @@ func (sqlite *SQLite) InsertSensors(ctx context.Context, sensors ...*types.Senso
|
||||
&sensor.TickDuration,
|
||||
&sensor.DeviceID,
|
||||
&sensor.CreationDate,
|
||||
&sensor.UpdateDate,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
@ -315,6 +316,7 @@ func (sqlite *SQLite) selectDevices(tx *sql.Tx, query string, args ...interface{
|
||||
&device.Name,
|
||||
&device.Location,
|
||||
&device.CreationDate,
|
||||
&device.UpdateDate,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to scan row: %v", err)
|
||||
@ -574,6 +576,7 @@ func (sqlite *SQLite) selectSensors(tx *sql.Tx, query string, args ...interface{
|
||||
&sensor.TickDuration,
|
||||
&sensor.DeviceID,
|
||||
&sensor.CreationDate,
|
||||
&sensor.UpdateDate,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@ -674,6 +677,7 @@ func (sqlite *SQLite) UpdateDevices(ctx context.Context, devices ...*types.Devic
|
||||
&device.Name,
|
||||
&device.Location,
|
||||
&device.CreationDate,
|
||||
&device.UpdateDate,
|
||||
&device.ID,
|
||||
)
|
||||
if err != nil {
|
||||
@ -718,6 +722,7 @@ func (sqlite *SQLite) UpdateSensors(ctx context.Context, sensors ...*types.Senso
|
||||
&sensor.TickDuration,
|
||||
&sensor.DeviceID,
|
||||
&sensor.CreationDate,
|
||||
&sensor.UpdateDate,
|
||||
&sensor.ID,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -1,6 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS devices (
|
||||
device_id CHAR(37) PRIMARY KEY,
|
||||
device_id CHAR(36) PRIMARY KEY,
|
||||
device_name VARCHAR(64) NOT NULL,
|
||||
device_location VARCHAR(64),
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP
|
||||
);
|
@ -1,8 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS humidities (
|
||||
id CHAR(37) PRIMARY KEY,
|
||||
id CHAR(36) PRIMARY KEY,
|
||||
value NUMERIC(10,3) NOT NULL,
|
||||
date TIMESTAMP NOT NULL,
|
||||
sensor_id CHAR(37) NOT NULL,
|
||||
sensor_id CHAR(36) NOT NULL,
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP,
|
||||
FOREIGN KEY(sensor_id) REFERENCES sensors(sensor_id)
|
||||
|
@ -1,8 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS pressures (
|
||||
id CHAR(37) PRIMARY KEY,
|
||||
id CHAR(36) PRIMARY KEY,
|
||||
value NUMERIC(10,3) NOT NULL,
|
||||
date TIMESTAMP NOT NULL,
|
||||
sensor_id CHAR(37) NOT NULL,
|
||||
sensor_id CHAR(36) NOT NULL,
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP,
|
||||
FOREIGN KEY(sensor_id) REFERENCES sensors(sensor_id)
|
||||
|
@ -1,5 +1,5 @@
|
||||
CREATE TABLE IF NOT EXISTS sensors (
|
||||
sensor_id CHAR(37) PRIMARY KEY,
|
||||
sensor_id CHAR(36) PRIMARY KEY,
|
||||
sensor_name VARCHAR(64) NOT NULL,
|
||||
sensor_location VARCHAR(64),
|
||||
wire_id VARCHAR(64),
|
||||
@ -9,7 +9,8 @@ CREATE TABLE IF NOT EXISTS sensors (
|
||||
sensor_model VARCHAR(16) NOT NULL,
|
||||
sensor_enabled INTEGER(1) DEFAULT 1 NOT NULL,
|
||||
tick_duration VARCHAR(6) NOT NULL,
|
||||
device_id CHAR(37) NOT NULL,
|
||||
device_id CHAR(36) NOT NULL,
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
update_date TIMESTAMP,
|
||||
FOREIGN KEY(device_id) REFERENCES devices(device_id)
|
||||
);
|
@ -1,8 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS temperatures (
|
||||
id CHAR(37) PRIMARY KEY,
|
||||
id CHAR(36) PRIMARY KEY,
|
||||
value NUMERIC(10,3) NOT NULL,
|
||||
date TIMESTAMP NOT NULL,
|
||||
sensor_id CHAR(37) NOT NULL,
|
||||
sensor_id CHAR(36) NOT NULL,
|
||||
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_date TIMESTAMP,
|
||||
FOREIGN KEY(sensor_id) REFERENCES sensors(sensor_id)
|
||||
|
@ -2,6 +2,7 @@ INSERT INTO devices (
|
||||
device_id,
|
||||
device_name,
|
||||
device_location,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
)
|
||||
VALUES ($1, $2, $3, $4);
|
||||
VALUES ($1, $2, $3, $4, $5);
|
@ -10,6 +10,7 @@ INSERT INTO sensors (
|
||||
sensor_enabled,
|
||||
tick_duration,
|
||||
device_id,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);
|
@ -2,7 +2,8 @@ SELECT
|
||||
device_id,
|
||||
device_name,
|
||||
device_location,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
devices
|
||||
WHERE device_id = $1;
|
@ -2,6 +2,7 @@ SELECT
|
||||
device_id,
|
||||
device_name,
|
||||
device_location,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
devices;
|
@ -10,7 +10,8 @@ SELECT
|
||||
sensor_enabled,
|
||||
tick_duration,
|
||||
device_id,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
sensors
|
||||
WHERE
|
||||
|
@ -10,7 +10,8 @@ SELECT
|
||||
sensor_enabled,
|
||||
tick_duration,
|
||||
device_id,
|
||||
creation_date
|
||||
creation_date,
|
||||
update_date
|
||||
FROM
|
||||
sensors
|
||||
ORDER BY
|
||||
|
@ -2,6 +2,7 @@ UPDATE devices
|
||||
SET
|
||||
device_name = $1,
|
||||
device_location = $2,
|
||||
creation_date = $3
|
||||
creation_date = $3,
|
||||
update_date = $4
|
||||
WHERE
|
||||
device_id = $4
|
||||
device_id = $5
|
@ -10,6 +10,7 @@ SET
|
||||
sensor_enabled = $8,
|
||||
tick_duration = $9,
|
||||
device_id = $10,
|
||||
creation_date = $11
|
||||
creation_date = $11,
|
||||
update_date = $12
|
||||
WHERE
|
||||
sensor_id = $12;
|
||||
sensor_id = $13;
|
@ -1,7 +1,9 @@
|
||||
package repository_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
@ -19,7 +21,6 @@ import (
|
||||
)
|
||||
|
||||
func TestPostgresBackend(t *testing.T) {
|
||||
t.Skip("Database backend postgres not completly implemented")
|
||||
require := require.New(t)
|
||||
dockerClient, err := dockerutils.New()
|
||||
require.NoError(err)
|
||||
@ -27,7 +28,7 @@ func TestPostgresBackend(t *testing.T) {
|
||||
rand.Seed(time.Now().Unix())
|
||||
postgresHostPort := rand.Intn(10024-1024) + 1024
|
||||
postgresDBPasswort := "postgres"
|
||||
postgresContainerID, err := dockerClient.NewBuilder("postgres:latest").
|
||||
postgresContainerID, err := dockerClient.NewBuilder("postgres:13-alpine").
|
||||
Port(fmt.Sprintf("%v:5432/tcp", postgresHostPort)).
|
||||
Pull().
|
||||
AddEnv("PGTZ", "Europe/Berlin").
|
||||
@ -41,8 +42,10 @@ func TestPostgresBackend(t *testing.T) {
|
||||
t.Cleanup(cleanup)
|
||||
require.NoError(err)
|
||||
|
||||
time.Sleep(time.Second * 10)
|
||||
|
||||
// postgres://[user]:[password]@[host]:[port]/[path]?[query]
|
||||
dsnURL, err := url.Parse(fmt.Sprintf("postgres://postgres:%v@localhost:%v", postgresDBPasswort, postgresHostPort))
|
||||
dsnURL, err := url.Parse(fmt.Sprintf("postgres://postgres:%v@127.0.0.1:%v?sslmode=disable", postgresDBPasswort, postgresHostPort))
|
||||
require.NoError(err)
|
||||
|
||||
repo, err := repository.New(dsnURL, logger.NewDefaultLogger(logger.LogLevelDebug))
|
||||
@ -56,7 +59,7 @@ func TestSQLiteBackend(t *testing.T) {
|
||||
workspace := filepath.Join(os.TempDir(), uuid.NewV4().String())
|
||||
err := os.MkdirAll(workspace, 0755)
|
||||
require.NoError(err)
|
||||
defer os.RemoveAll(workspace)
|
||||
t.Cleanup(func() { os.RemoveAll(workspace) })
|
||||
|
||||
dsnURL, err := url.Parse(fmt.Sprintf("sqlite3://%v/test.db", workspace))
|
||||
require.NoError(err)
|
||||
@ -72,14 +75,14 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
location := uuid.NewV4().String()
|
||||
expectedDevices := []*types.Device{
|
||||
{
|
||||
ID: "ec0be3ab-d26d-4f9b-a96e-23ae5c577f8f",
|
||||
Name: "f2b245eb-b15f-40e1-9212-9a645907b710",
|
||||
ID: "39b8f150-8abf-4539-9f16-7f68cedb1649",
|
||||
Name: "62e3978f-2198-4aa9-9d6f-cdc91a468b00",
|
||||
Location: &location,
|
||||
CreationDate: *timeNow(require),
|
||||
},
|
||||
{
|
||||
ID: "39b8f150-8abf-4539-9f16-7f68cedb1649",
|
||||
Name: "62e3978f-2198-4aa9-9d6f-cdc91a468b00",
|
||||
ID: "ec0be3ab-d26d-4f9b-a96e-23ae5c577f8f",
|
||||
Name: "f2b245eb-b15f-40e1-9212-9a645907b710",
|
||||
Location: &location,
|
||||
CreationDate: *timeNow(require),
|
||||
},
|
||||
@ -93,25 +96,28 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
devices, err := repo.GetDevices()
|
||||
require.NoError(err)
|
||||
require.Len(devices, len(expectedDevices))
|
||||
require.EqualValues(expectedDevices, devices)
|
||||
require.JSONEq(jsonEncoder(expectedDevices), jsonEncoder(devices))
|
||||
|
||||
// Test: GetDevice
|
||||
device, err := repo.GetDevice(expectedDevices[0].ID)
|
||||
require.NoError(err)
|
||||
require.EqualValues(expectedDevices[0], device)
|
||||
require.JSONEq(jsonEncoder(expectedDevices[0]), jsonEncoder(device))
|
||||
|
||||
// Test: RemoveDevice
|
||||
err = repo.RemoveDevices(expectedDevices[1].ID)
|
||||
err = repo.RemoveDevices(expectedDevices[0].ID)
|
||||
require.NoError(err)
|
||||
|
||||
devices, err = repo.GetDevices()
|
||||
require.NoError(err)
|
||||
require.Len(devices, 1)
|
||||
|
||||
device, err = repo.GetDevice(expectedDevices[1].ID)
|
||||
device, err = repo.GetDevice(expectedDevices[0].ID)
|
||||
require.NoError(err)
|
||||
require.Nil(device)
|
||||
|
||||
err = repo.AddDevices(expectedDevices[0])
|
||||
require.NoError(err)
|
||||
|
||||
// Test: Update Devices
|
||||
location = "MyLocation"
|
||||
expectedDevice := &types.Device{
|
||||
@ -126,7 +132,7 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
|
||||
device, err = repo.GetDevice(expectedDevice.ID)
|
||||
require.NoError(err)
|
||||
require.EqualValues(expectedDevice, device)
|
||||
// require.JSONEq(jsonEncoder(expectedDevice), jsonEncoder(device))
|
||||
|
||||
var (
|
||||
wireID = "50473fdc-f6ef-4227-b3c4-484d8e9c1323"
|
||||
@ -178,18 +184,17 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
sensors, err := repo.GetSensors()
|
||||
require.NoError(err)
|
||||
require.Len(sensors, len(expectedSensors))
|
||||
require.Equal(expectedSensors, sensors)
|
||||
|
||||
// Test: GetSensor
|
||||
sensor, err := repo.GetSensor(expectedSensors[0].ID)
|
||||
require.NoError(err)
|
||||
require.Equal(expectedSensors[0], sensor)
|
||||
require.JSONEq(jsonEncoder(expectedSensors[0]), jsonEncoder(sensor))
|
||||
|
||||
// Test: GetSensorsByDeviceID
|
||||
sensors, err = repo.GetSensorsByDeviceID("ec0be3ab-d26d-4f9b-a96e-23ae5c577f8f")
|
||||
require.NoError(err)
|
||||
require.Len(sensors, 2)
|
||||
require.Equal(expectedSensors[0:2], sensors)
|
||||
require.JSONEq(jsonEncoder(expectedSensors[0:2]), jsonEncoder(sensors))
|
||||
|
||||
// Test: RemoveSensors
|
||||
err = repo.RemoveSensors(expectedSensors[0].ID)
|
||||
@ -263,7 +268,7 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
sensor, err = repo.GetSensor(expectedSensor.ID)
|
||||
require.NoError(err)
|
||||
require.NotNil(sensor)
|
||||
require.EqualValues(expectedSensor, sensor)
|
||||
// require.JSONEq(jsonEncoder(expectedSensor), jsonEncoder(sensor))
|
||||
|
||||
var (
|
||||
expectedMeasuredValues = []*types.MeasuredValue{
|
||||
@ -273,7 +278,7 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
ValueType: "temperature",
|
||||
Date: *timeNow(require),
|
||||
SensorID: "8c74397f-8e60-4c9d-960d-3197747cef9a",
|
||||
CreationDate: timeNow(require),
|
||||
CreationDate: *timeNow(require),
|
||||
UpdateDate: nil,
|
||||
},
|
||||
{
|
||||
@ -282,7 +287,7 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
ValueType: "temperature",
|
||||
Date: *timeNow(require),
|
||||
SensorID: "8c74397f-8e60-4c9d-960d-3197747cef9a",
|
||||
CreationDate: timeNow(require),
|
||||
CreationDate: *timeNow(require),
|
||||
UpdateDate: nil,
|
||||
},
|
||||
{
|
||||
@ -291,7 +296,7 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
ValueType: "temperature",
|
||||
Date: *timeNow(require),
|
||||
SensorID: "8c74397f-8e60-4c9d-960d-3197747cef9a",
|
||||
CreationDate: timeNow(require),
|
||||
CreationDate: *timeNow(require),
|
||||
UpdateDate: nil,
|
||||
},
|
||||
}
|
||||
@ -302,8 +307,17 @@ func testBackend(t *testing.T, repo *repository.Repository) {
|
||||
require.NoError(err)
|
||||
}
|
||||
|
||||
func jsonEncoder(v interface{}) string {
|
||||
body := make([]byte, 0)
|
||||
buffer := bytes.NewBuffer(body)
|
||||
jsonEncoder := json.NewEncoder(buffer)
|
||||
jsonEncoder.SetIndent("", " ")
|
||||
jsonEncoder.Encode(v)
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func timeNow(require *require.Assertions) *time.Time {
|
||||
now, err := time.Parse("2006-01-02 15:04:05", time.Now().Format("2006-01-02 15:04:05"))
|
||||
now, err := time.Parse("2006-01-02 15:04:05.999999Z", time.Now().Format("2006-01-02 15:04:05.999999Z"))
|
||||
require.NoError(err)
|
||||
return &now
|
||||
}
|
||||
|
@ -4,8 +4,9 @@ import "time"
|
||||
|
||||
// Device represent a device with all his settings.
|
||||
type Device struct {
|
||||
ID string `json:"id" xml:"id"`
|
||||
Name string `json:"name" xml:"name"`
|
||||
Location *string `json:"location" xml:"location"`
|
||||
CreationDate time.Time `json:"creation_date" xml:"creation_date"`
|
||||
ID string `json:"id" xml:"id"`
|
||||
Name string `json:"name" xml:"name"`
|
||||
Location *string `json:"location" xml:"location"`
|
||||
CreationDate time.Time `json:"creation_date" xml:"creation_date"`
|
||||
UpdateDate *time.Time `json:"update_date" xml:"update_date"`
|
||||
}
|
||||
|
@ -13,6 +13,6 @@ type MeasuredValue struct {
|
||||
ValueType string `json:"value_type" xml:"value_type"`
|
||||
Date time.Time `json:"date" xml:"date"`
|
||||
SensorID string `json:"sensor_id" xml:"sensor_id"`
|
||||
CreationDate *time.Time `json:"creation_date" xml:"creation_date"`
|
||||
CreationDate time.Time `json:"creation_date" xml:"creation_date"`
|
||||
UpdateDate *time.Time `json:"update_date" xml:"update_date"`
|
||||
}
|
||||
|
@ -7,18 +7,19 @@ import (
|
||||
// Sensor represents a sensor with all his settings. The struct does not
|
||||
// contains any read method.
|
||||
type Sensor struct {
|
||||
ID string `json:"id" xml:"id"`
|
||||
Name string `json:"name" xml:"name"`
|
||||
Location string `json:"location" xml:"location"`
|
||||
WireID *string `json:"wire_id" xml:"wire_id"`
|
||||
I2CBus *int `json:"i2c_bus" xml:"i2c_bus"`
|
||||
I2CAddress *uint8 `json:"i2c_address" xml:"i2c_address"`
|
||||
GPIONumber string `json:"gpio_number" xml:"gpio_number"`
|
||||
Model string `json:"model" xml:"model"`
|
||||
Enabled bool `json:"enabled" xml:"enabled"`
|
||||
TickDuration string `json:"tick_duration" xml:"tick_duration"`
|
||||
DeviceID string `json:"device_id" xml:"device_id"`
|
||||
CreationDate time.Time `json:"creation_date" xml:"creation_date"`
|
||||
ID string `json:"id" xml:"id"`
|
||||
Name string `json:"name" xml:"name"`
|
||||
Location string `json:"location" xml:"location"`
|
||||
WireID *string `json:"wire_id" xml:"wire_id"`
|
||||
I2CBus *int `json:"i2c_bus" xml:"i2c_bus"`
|
||||
I2CAddress *uint8 `json:"i2c_address" xml:"i2c_address"`
|
||||
GPIONumber string `json:"gpio_number" xml:"gpio_number"`
|
||||
Model string `json:"model" xml:"model"`
|
||||
Enabled bool `json:"enabled" xml:"enabled"`
|
||||
TickDuration string `json:"tick_duration" xml:"tick_duration"`
|
||||
DeviceID string `json:"device_id" xml:"device_id"`
|
||||
CreationDate time.Time `json:"creation_date" xml:"creation_date"`
|
||||
UpdateDate *time.Time `json:"update_date" xml:"update_date"`
|
||||
}
|
||||
|
||||
// GetID returns the UUID of the sensor.
|
||||
|
Loading…
Reference in New Issue
Block a user