From 4931c63c10ae25723476e8a67620db90a3f3a3f2 Mon Sep 17 00:00:00 2001 From: Markus Pesch Date: Mon, 1 Jun 2020 22:36:57 +0200 Subject: [PATCH] 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. --- Makefile | 1 + go.mod | 8 +- go.sum | 40 ++ pkg/repository/db/db.go | 23 +- pkg/repository/db/postgres.go | 613 ++++++++++++++---- .../db/postgres/createTableDevices.sql | 7 + .../db/postgres/createTableHumidities.sql | 14 + .../db/postgres/createTablePressures.sql | 14 + .../db/postgres/createTableSensors.sql | 21 + .../db/postgres/createTableTemperatures.sql | 14 + pkg/repository/db/postgres/deleteDevice.sql | 2 +- pkg/repository/db/postgres/insertDevice.sql | 5 +- pkg/repository/db/postgres/insertHumidity.sql | 9 +- pkg/repository/db/postgres/insertPressure.sql | 9 +- pkg/repository/db/postgres/insertSensor.sql | 6 +- .../db/postgres/insertTemperature.sql | 9 +- pkg/repository/db/postgres/selectDevice.sql | 3 +- pkg/repository/db/postgres/selectDevices.sql | 7 +- .../db/postgres/selectHumidities.sql | 9 + pkg/repository/db/postgres/selectHumidity.sql | 11 + pkg/repository/db/postgres/selectPressure.sql | 11 + .../db/postgres/selectPressures.sql | 9 + pkg/repository/db/postgres/selectSensor.sql | 4 +- pkg/repository/db/postgres/selectSensors.sql | 8 +- .../db/postgres/selectTemperature.sql | 11 + .../db/postgres/selectTemperatures.sql | 9 + pkg/repository/db/postgres/updateDevice.sql | 12 +- pkg/repository/db/postgres/updateSensor.sql | 23 +- pkg/repository/db/sqlite.go | 9 +- .../db/sqlite3/createTableDevices.sql | 5 +- .../db/sqlite3/createTableHumidities.sql | 4 +- .../db/sqlite3/createTablePressures.sql | 4 +- .../db/sqlite3/createTableSensors.sql | 5 +- .../db/sqlite3/createTableTemperatures.sql | 4 +- pkg/repository/db/sqlite3/insertDevice.sql | 5 +- pkg/repository/db/sqlite3/insertSensor.sql | 5 +- pkg/repository/db/sqlite3/selectDevice.sql | 3 +- pkg/repository/db/sqlite3/selectDevices.sql | 3 +- pkg/repository/db/sqlite3/selectSensor.sql | 3 +- pkg/repository/db/sqlite3/selectSensors.sql | 3 +- pkg/repository/db/sqlite3/updateDevice.sql | 5 +- pkg/repository/db/sqlite3/updateSensor.sql | 5 +- pkg/repository/repository_test.go | 56 +- pkg/types/device.go | 9 +- pkg/types/measuredValue.go | 2 +- pkg/types/sensor.go | 25 +- 46 files changed, 822 insertions(+), 245 deletions(-) create mode 100644 pkg/repository/db/postgres/createTableDevices.sql create mode 100644 pkg/repository/db/postgres/createTableHumidities.sql create mode 100644 pkg/repository/db/postgres/createTablePressures.sql create mode 100644 pkg/repository/db/postgres/createTableSensors.sql create mode 100644 pkg/repository/db/postgres/createTableTemperatures.sql create mode 100644 pkg/repository/db/postgres/selectHumidities.sql create mode 100644 pkg/repository/db/postgres/selectHumidity.sql create mode 100644 pkg/repository/db/postgres/selectPressure.sql create mode 100644 pkg/repository/db/postgres/selectPressures.sql create mode 100644 pkg/repository/db/postgres/selectTemperature.sql create mode 100644 pkg/repository/db/postgres/selectTemperatures.sql diff --git a/Makefile b/Makefile index f589a67..1ac805d 100644 --- a/Makefile +++ b/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} \ diff --git a/go.mod b/go.mod index c45729c..c234172 100644 --- a/go.mod +++ b/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 ) diff --git a/go.sum b/go.sum index dc26bad..d5c6758 100644 --- a/go.sum +++ b/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= diff --git a/pkg/repository/db/db.go b/pkg/repository/db/db.go index e6b28e5..62bf605 100644 --- a/pkg/repository/db/db.go +++ b/pkg/repository/db/db.go @@ -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": diff --git a/pkg/repository/db/postgres.go b/pkg/repository/db/postgres.go index aad6463..d2f7c1b 100644 --- a/pkg/repository/db/postgres.go +++ b/pkg/repository/db/postgres.go @@ -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() } diff --git a/pkg/repository/db/postgres/createTableDevices.sql b/pkg/repository/db/postgres/createTableDevices.sql new file mode 100644 index 0000000..1b823e1 --- /dev/null +++ b/pkg/repository/db/postgres/createTableDevices.sql @@ -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 +); \ No newline at end of file diff --git a/pkg/repository/db/postgres/createTableHumidities.sql b/pkg/repository/db/postgres/createTableHumidities.sql new file mode 100644 index 0000000..b5355cd --- /dev/null +++ b/pkg/repository/db/postgres/createTableHumidities.sql @@ -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; \ No newline at end of file diff --git a/pkg/repository/db/postgres/createTablePressures.sql b/pkg/repository/db/postgres/createTablePressures.sql new file mode 100644 index 0000000..1844cd6 --- /dev/null +++ b/pkg/repository/db/postgres/createTablePressures.sql @@ -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; \ No newline at end of file diff --git a/pkg/repository/db/postgres/createTableSensors.sql b/pkg/repository/db/postgres/createTableSensors.sql new file mode 100644 index 0000000..0952753 --- /dev/null +++ b/pkg/repository/db/postgres/createTableSensors.sql @@ -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; \ No newline at end of file diff --git a/pkg/repository/db/postgres/createTableTemperatures.sql b/pkg/repository/db/postgres/createTableTemperatures.sql new file mode 100644 index 0000000..bed45aa --- /dev/null +++ b/pkg/repository/db/postgres/createTableTemperatures.sql @@ -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; \ No newline at end of file diff --git a/pkg/repository/db/postgres/deleteDevice.sql b/pkg/repository/db/postgres/deleteDevice.sql index 22ad7fa..5d75ead 100644 --- a/pkg/repository/db/postgres/deleteDevice.sql +++ b/pkg/repository/db/postgres/deleteDevice.sql @@ -1,2 +1,2 @@ -DELETE FROM sensors +DELETE FROM devices WHERE device_id = $1; \ No newline at end of file diff --git a/pkg/repository/db/postgres/insertDevice.sql b/pkg/repository/db/postgres/insertDevice.sql index d197f24..6dfe3f6 100644 --- a/pkg/repository/db/postgres/insertDevice.sql +++ b/pkg/repository/db/postgres/insertDevice.sql @@ -2,6 +2,7 @@ INSERT INTO devices ( device_id, device_name, device_location, - creation_date + creation_date, + update_date ) -VALUES ($1, $2, $3, $4); \ No newline at end of file +VALUES ($1, $2, $3, $4, $5); \ No newline at end of file diff --git a/pkg/repository/db/postgres/insertHumidity.sql b/pkg/repository/db/postgres/insertHumidity.sql index e7a7041..b79bf52 100644 --- a/pkg/repository/db/postgres/insertHumidity.sql +++ b/pkg/repository/db/postgres/insertHumidity.sql @@ -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); \ No newline at end of file +VALUES ($1, $2, $3, $4, $5, $6); \ No newline at end of file diff --git a/pkg/repository/db/postgres/insertPressure.sql b/pkg/repository/db/postgres/insertPressure.sql index 8add4b5..7f68da9 100644 --- a/pkg/repository/db/postgres/insertPressure.sql +++ b/pkg/repository/db/postgres/insertPressure.sql @@ -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); \ No newline at end of file +VALUES ($1, $2, $3, $4, $5, $6); \ No newline at end of file diff --git a/pkg/repository/db/postgres/insertSensor.sql b/pkg/repository/db/postgres/insertSensor.sql index 2aca33a..5350150 100644 --- a/pkg/repository/db/postgres/insertSensor.sql +++ b/pkg/repository/db/postgres/insertSensor.sql @@ -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); \ No newline at end of file +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13); \ No newline at end of file diff --git a/pkg/repository/db/postgres/insertTemperature.sql b/pkg/repository/db/postgres/insertTemperature.sql index 520555a..9afb3b2 100644 --- a/pkg/repository/db/postgres/insertTemperature.sql +++ b/pkg/repository/db/postgres/insertTemperature.sql @@ -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); \ No newline at end of file +VALUES ($1, $2, $3, $4, $5, $6); \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectDevice.sql b/pkg/repository/db/postgres/selectDevice.sql index a56b927..e62bfcc 100644 --- a/pkg/repository/db/postgres/selectDevice.sql +++ b/pkg/repository/db/postgres/selectDevice.sql @@ -2,7 +2,8 @@ SELECT device_id, device_name, device_location, - creation_date + creation_date, + update_date FROM devices WHERE device_id = $1; \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectDevices.sql b/pkg/repository/db/postgres/selectDevices.sql index 81f256e..fbb5f68 100644 --- a/pkg/repository/db/postgres/selectDevices.sql +++ b/pkg/repository/db/postgres/selectDevices.sql @@ -2,6 +2,9 @@ SELECT device_id, device_name, device_location, - creation_date + creation_date, + update_date FROM - devices; \ No newline at end of file + devices +ORDER BY + device_id ASC; \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectHumidities.sql b/pkg/repository/db/postgres/selectHumidities.sql new file mode 100644 index 0000000..b6c3192 --- /dev/null +++ b/pkg/repository/db/postgres/selectHumidities.sql @@ -0,0 +1,9 @@ +SELECT + id, + value, + date, + sensor_id, + creation_date, + update_date +FROM + humidities; \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectHumidity.sql b/pkg/repository/db/postgres/selectHumidity.sql new file mode 100644 index 0000000..78ebc28 --- /dev/null +++ b/pkg/repository/db/postgres/selectHumidity.sql @@ -0,0 +1,11 @@ +SELECT + id, + value, + date, + sensor_id, + creation_date, + update_date +FROM + humidities +WHERE + humidity_id = $1 \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectPressure.sql b/pkg/repository/db/postgres/selectPressure.sql new file mode 100644 index 0000000..08f8a71 --- /dev/null +++ b/pkg/repository/db/postgres/selectPressure.sql @@ -0,0 +1,11 @@ +SELECT + id, + value, + date, + sensor_id, + creation_date, + update_date +FROM + pressures +WHERE + pressure_id = $1 \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectPressures.sql b/pkg/repository/db/postgres/selectPressures.sql new file mode 100644 index 0000000..e13549a --- /dev/null +++ b/pkg/repository/db/postgres/selectPressures.sql @@ -0,0 +1,9 @@ +SELECT + id, + value, + date, + sensor_id, + creation_date, + update_date +FROM + pressures; \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectSensor.sql b/pkg/repository/db/postgres/selectSensor.sql index 0d6f164..5cfee73 100644 --- a/pkg/repository/db/postgres/selectSensor.sql +++ b/pkg/repository/db/postgres/selectSensor.sql @@ -8,8 +8,10 @@ SELECT gpio_number, sensor_model, sensor_enabled, + tick_duration, device_id, - creation_date + creation_date, + update_date FROM sensors WHERE diff --git a/pkg/repository/db/postgres/selectSensors.sql b/pkg/repository/db/postgres/selectSensors.sql index 0c85bc4..e8b83bb 100644 --- a/pkg/repository/db/postgres/selectSensors.sql +++ b/pkg/repository/db/postgres/selectSensors.sql @@ -8,7 +8,11 @@ SELECT gpio_number, sensor_model, sensor_enabled, + tick_duration, device_id, - creation_date + creation_date, + update_date FROM - sensors; \ No newline at end of file + sensors +ORDER BY + sensor_id ASC; \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectTemperature.sql b/pkg/repository/db/postgres/selectTemperature.sql new file mode 100644 index 0000000..51ab33a --- /dev/null +++ b/pkg/repository/db/postgres/selectTemperature.sql @@ -0,0 +1,11 @@ +SELECT + id, + value, + date, + sensor_id, + creation_date, + update_date +FROM + temperatures +WHERE + temperature_id = $1 \ No newline at end of file diff --git a/pkg/repository/db/postgres/selectTemperatures.sql b/pkg/repository/db/postgres/selectTemperatures.sql new file mode 100644 index 0000000..ce768ee --- /dev/null +++ b/pkg/repository/db/postgres/selectTemperatures.sql @@ -0,0 +1,9 @@ +SELECT + id, + value, + date, + sensor_id, + creation_date, + update_date +FROM + temperatures \ No newline at end of file diff --git a/pkg/repository/db/postgres/updateDevice.sql b/pkg/repository/db/postgres/updateDevice.sql index 997967d..34056a9 100644 --- a/pkg/repository/db/postgres/updateDevice.sql +++ b/pkg/repository/db/postgres/updateDevice.sql @@ -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, \ No newline at end of file + device_id = $5 \ No newline at end of file diff --git a/pkg/repository/db/postgres/updateSensor.sql b/pkg/repository/db/postgres/updateSensor.sql index 9173cf2..a00aa31 100644 --- a/pkg/repository/db/postgres/updateSensor.sql +++ b/pkg/repository/db/postgres/updateSensor.sql @@ -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; \ No newline at end of file + sensor_id = $13; \ No newline at end of file diff --git a/pkg/repository/db/sqlite.go b/pkg/repository/db/sqlite.go index 196600e..8b69228 100644 --- a/pkg/repository/db/sqlite.go +++ b/pkg/repository/db/sqlite.go @@ -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 { diff --git a/pkg/repository/db/sqlite3/createTableDevices.sql b/pkg/repository/db/sqlite3/createTableDevices.sql index 88b48ee..087d558 100644 --- a/pkg/repository/db/sqlite3/createTableDevices.sql +++ b/pkg/repository/db/sqlite3/createTableDevices.sql @@ -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 ); \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/createTableHumidities.sql b/pkg/repository/db/sqlite3/createTableHumidities.sql index da02a9c..680b117 100644 --- a/pkg/repository/db/sqlite3/createTableHumidities.sql +++ b/pkg/repository/db/sqlite3/createTableHumidities.sql @@ -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) diff --git a/pkg/repository/db/sqlite3/createTablePressures.sql b/pkg/repository/db/sqlite3/createTablePressures.sql index 0f6cc27..df72076 100644 --- a/pkg/repository/db/sqlite3/createTablePressures.sql +++ b/pkg/repository/db/sqlite3/createTablePressures.sql @@ -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) diff --git a/pkg/repository/db/sqlite3/createTableSensors.sql b/pkg/repository/db/sqlite3/createTableSensors.sql index d189f26..7c59470 100644 --- a/pkg/repository/db/sqlite3/createTableSensors.sql +++ b/pkg/repository/db/sqlite3/createTableSensors.sql @@ -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) ); \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/createTableTemperatures.sql b/pkg/repository/db/sqlite3/createTableTemperatures.sql index b2220f9..9e0fa01 100644 --- a/pkg/repository/db/sqlite3/createTableTemperatures.sql +++ b/pkg/repository/db/sqlite3/createTableTemperatures.sql @@ -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) diff --git a/pkg/repository/db/sqlite3/insertDevice.sql b/pkg/repository/db/sqlite3/insertDevice.sql index d197f24..6dfe3f6 100644 --- a/pkg/repository/db/sqlite3/insertDevice.sql +++ b/pkg/repository/db/sqlite3/insertDevice.sql @@ -2,6 +2,7 @@ INSERT INTO devices ( device_id, device_name, device_location, - creation_date + creation_date, + update_date ) -VALUES ($1, $2, $3, $4); \ No newline at end of file +VALUES ($1, $2, $3, $4, $5); \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/insertSensor.sql b/pkg/repository/db/sqlite3/insertSensor.sql index ae1c3e8..5350150 100644 --- a/pkg/repository/db/sqlite3/insertSensor.sql +++ b/pkg/repository/db/sqlite3/insertSensor.sql @@ -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); \ No newline at end of file +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13); \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/selectDevice.sql b/pkg/repository/db/sqlite3/selectDevice.sql index a56b927..e62bfcc 100644 --- a/pkg/repository/db/sqlite3/selectDevice.sql +++ b/pkg/repository/db/sqlite3/selectDevice.sql @@ -2,7 +2,8 @@ SELECT device_id, device_name, device_location, - creation_date + creation_date, + update_date FROM devices WHERE device_id = $1; \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/selectDevices.sql b/pkg/repository/db/sqlite3/selectDevices.sql index 81f256e..71748c4 100644 --- a/pkg/repository/db/sqlite3/selectDevices.sql +++ b/pkg/repository/db/sqlite3/selectDevices.sql @@ -2,6 +2,7 @@ SELECT device_id, device_name, device_location, - creation_date + creation_date, + update_date FROM devices; \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/selectSensor.sql b/pkg/repository/db/sqlite3/selectSensor.sql index 9a42af7..5cfee73 100644 --- a/pkg/repository/db/sqlite3/selectSensor.sql +++ b/pkg/repository/db/sqlite3/selectSensor.sql @@ -10,7 +10,8 @@ SELECT sensor_enabled, tick_duration, device_id, - creation_date + creation_date, + update_date FROM sensors WHERE diff --git a/pkg/repository/db/sqlite3/selectSensors.sql b/pkg/repository/db/sqlite3/selectSensors.sql index 87978b3..6f4206b 100644 --- a/pkg/repository/db/sqlite3/selectSensors.sql +++ b/pkg/repository/db/sqlite3/selectSensors.sql @@ -10,7 +10,8 @@ SELECT sensor_enabled, tick_duration, device_id, - creation_date + creation_date, + update_date FROM sensors ORDER BY diff --git a/pkg/repository/db/sqlite3/updateDevice.sql b/pkg/repository/db/sqlite3/updateDevice.sql index 9a3836f..34056a9 100644 --- a/pkg/repository/db/sqlite3/updateDevice.sql +++ b/pkg/repository/db/sqlite3/updateDevice.sql @@ -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 \ No newline at end of file + device_id = $5 \ No newline at end of file diff --git a/pkg/repository/db/sqlite3/updateSensor.sql b/pkg/repository/db/sqlite3/updateSensor.sql index 57ab62c..a00aa31 100644 --- a/pkg/repository/db/sqlite3/updateSensor.sql +++ b/pkg/repository/db/sqlite3/updateSensor.sql @@ -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; \ No newline at end of file + sensor_id = $13; \ No newline at end of file diff --git a/pkg/repository/repository_test.go b/pkg/repository/repository_test.go index 69c71d0..050f1ab 100644 --- a/pkg/repository/repository_test.go +++ b/pkg/repository/repository_test.go @@ -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 } diff --git a/pkg/types/device.go b/pkg/types/device.go index cf9fab4..84c6a69 100644 --- a/pkg/types/device.go +++ b/pkg/types/device.go @@ -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"` } diff --git a/pkg/types/measuredValue.go b/pkg/types/measuredValue.go index cb79b87..70435e6 100644 --- a/pkg/types/measuredValue.go +++ b/pkg/types/measuredValue.go @@ -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"` } diff --git a/pkg/types/sensor.go b/pkg/types/sensor.go index 38c13ec..5f532fb 100644 --- a/pkg/types/sensor.go +++ b/pkg/types/sensor.go @@ -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.