From 81a74901916ed4239675225c8403fb0d0d54a955 Mon Sep 17 00:00:00 2001 From: louis Date: Fri, 6 Oct 2023 20:14:43 +0200 Subject: [PATCH] Rename Storage to StormStorage --- cmd/run.go | 4 +- go.mod | 17 +- go.sum | 38 +- internal/api/api.go | 4 +- internal/api/middleware/auth/auth.go | 6 +- internal/api/middleware/me/me.go | 2 +- internal/api/middleware/message/message.go | 2 +- internal/api/middleware/ticker/ticker.go | 4 +- internal/api/middleware/user/user.go | 2 +- internal/bridge/bridge.go | 2 +- internal/bridge/mastodon.go | 2 +- internal/bridge/telegram.go | 2 +- internal/storage/db.go | 13 - internal/storage/storage.go | 354 +---------------- internal/storage/storm_storage.go | 367 ++++++++++++++++++ ...{storage_test.go => storm_storage_test.go} | 2 +- 16 files changed, 432 insertions(+), 389 deletions(-) delete mode 100644 internal/storage/db.go create mode 100644 internal/storage/storm_storage.go rename internal/storage/{storage_test.go => storm_storage_test.go} (99%) diff --git a/cmd/run.go b/cmd/run.go index 7893270d..d7a5416c 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -40,7 +40,7 @@ var ( log.Fatal(http.ListenAndServe(cfg.MetricsListen, nil)) }() - store := storage.NewStorage(cfg.Database, cfg.UploadPath) + store := storage.NewStormStorage(cfg.Database, cfg.UploadPath) router := api.API(cfg, store) server := &http.Server{ Addr: cfg.Listen, @@ -72,7 +72,7 @@ var ( } ) -func firstRun(store storage.TickerStorage, config config.Config) { +func firstRun(store storage.Storage, config config.Config) { count, err := store.CountUser() if err != nil { log.Fatal("error using database") diff --git a/go.mod b/go.mod index 241846ab..b2618afd 100644 --- a/go.mod +++ b/go.mod @@ -14,13 +14,18 @@ require ( github.com/sethvargo/go-password v0.2.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.10.0 + github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 + github.com/swaggo/swag v1.16.2 github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f - golang.org/x/crypto v0.13.0 + golang.org/x/crypto v0.14.0 ) require ( + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -30,6 +35,10 @@ require ( github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-logr/logr v1.2.4 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/spec v0.20.4 // indirect + github.com/go-openapi/swag v0.19.15 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect @@ -41,10 +50,12 @@ require ( github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -56,7 +67,6 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect @@ -66,11 +76,12 @@ require ( github.com/ugorji/go/codec v1.2.11 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/net v0.14.0 // indirect - golang.org/x/sys v0.12.0 // indirect + golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.12.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 76bd968c..4b7f1f31 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,12 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.0 h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo= github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Sereal/Sereal v0.0.0-20190606082811-cf1bab6c7a3a h1:r3TT14Z4rWYwW2U8F1DkyM0dpvafwUsye+X3j1J5U3g= github.com/Sereal/Sereal v0.0.0-20190606082811-cf1bab6c7a3a/go.mod h1:D0JMgToj/WdxCgd30Kc1UcA9E+WdZoJqeVOuYW7iTBM= github.com/appleboy/gin-jwt/v2 v2.9.1 h1:l29et8iLW6omcHltsOP6LLk4s3v4g2FbFs0koxGWVZs= @@ -99,6 +105,16 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -203,6 +219,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= @@ -227,6 +245,10 @@ github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -244,6 +266,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= @@ -308,6 +331,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04= +github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E= github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -355,8 +380,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -426,6 +451,7 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= @@ -486,6 +512,7 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -499,8 +526,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -670,6 +697,7 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -677,8 +705,10 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/api/api.go b/internal/api/api.go index 3dcc2f20..8e079fb8 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -23,7 +23,7 @@ var log = logrus.New().WithField("package", "api") type handler struct { config config.Config - storage storage.TickerStorage + storage storage.Storage bridges bridge.Bridges } @@ -41,7 +41,7 @@ type handler struct { // @host localhost:8080 // @BasePath /v1 -func API(config config.Config, storage storage.TickerStorage) *gin.Engine { +func API(config config.Config, storage storage.Storage) *gin.Engine { handler := handler{ config: config, storage: storage, diff --git a/internal/api/middleware/auth/auth.go b/internal/api/middleware/auth/auth.go index 2fdf8316..e5e435ff 100644 --- a/internal/api/middleware/auth/auth.go +++ b/internal/api/middleware/auth/auth.go @@ -13,7 +13,7 @@ import ( var log = logrus.WithField("package", "auth") -func AuthMiddleware(s storage.TickerStorage, secret string) *jwt.GinJWTMiddleware { +func AuthMiddleware(s storage.Storage, secret string) *jwt.GinJWTMiddleware { config := &jwt.GinJWTMiddleware{ Realm: "ticker admin", Key: []byte(secret), @@ -36,7 +36,7 @@ func AuthMiddleware(s storage.TickerStorage, secret string) *jwt.GinJWTMiddlewar return middleware } -func Authenticator(s storage.TickerStorage) func(c *gin.Context) (interface{}, error) { +func Authenticator(s storage.Storage) func(c *gin.Context) (interface{}, error) { return func(c *gin.Context) (interface{}, error) { type login struct { Username string `form:"username" json:"username" binding:"required"` @@ -62,7 +62,7 @@ func Authenticator(s storage.TickerStorage) func(c *gin.Context) (interface{}, e } } -func Authorizator(s storage.TickerStorage) func(data interface{}, c *gin.Context) bool { +func Authorizator(s storage.Storage) func(data interface{}, c *gin.Context) bool { return func(data interface{}, c *gin.Context) bool { id := int(data.(float64)) diff --git a/internal/api/middleware/me/me.go b/internal/api/middleware/me/me.go index ab5fd48e..1280cca4 100644 --- a/internal/api/middleware/me/me.go +++ b/internal/api/middleware/me/me.go @@ -8,7 +8,7 @@ import ( "github.com/systemli/ticker/internal/storage" ) -func MeMiddleware(storage storage.TickerStorage) gin.HandlerFunc { +func MeMiddleware(storage storage.Storage) gin.HandlerFunc { return func(c *gin.Context) { userID, exists := c.Get("id") if !exists { diff --git a/internal/api/middleware/message/message.go b/internal/api/middleware/message/message.go index ac36105e..32bf6acd 100644 --- a/internal/api/middleware/message/message.go +++ b/internal/api/middleware/message/message.go @@ -10,7 +10,7 @@ import ( "github.com/systemli/ticker/internal/storage" ) -func PrefetchMessage(s storage.TickerStorage) gin.HandlerFunc { +func PrefetchMessage(s storage.Storage) gin.HandlerFunc { return func(c *gin.Context) { ticker, _ := helper.Ticker(c) diff --git a/internal/api/middleware/ticker/ticker.go b/internal/api/middleware/ticker/ticker.go index f64b0da2..f02bb03d 100644 --- a/internal/api/middleware/ticker/ticker.go +++ b/internal/api/middleware/ticker/ticker.go @@ -11,7 +11,7 @@ import ( "github.com/systemli/ticker/internal/util" ) -func PrefetchTicker(s storage.TickerStorage) gin.HandlerFunc { +func PrefetchTicker(s storage.Storage) gin.HandlerFunc { return func(c *gin.Context) { user, _ := helper.Me(c) tickerID, err := strconv.Atoi(c.Param("tickerID")) @@ -37,7 +37,7 @@ func PrefetchTicker(s storage.TickerStorage) gin.HandlerFunc { } } -func PrefetchTickerFromRequest(s storage.TickerStorage) gin.HandlerFunc { +func PrefetchTickerFromRequest(s storage.Storage) gin.HandlerFunc { return func(c *gin.Context) { domain, err := helper.GetDomain(c) if err != nil { diff --git a/internal/api/middleware/user/user.go b/internal/api/middleware/user/user.go index 8bd26de8..d0c37c40 100644 --- a/internal/api/middleware/user/user.go +++ b/internal/api/middleware/user/user.go @@ -9,7 +9,7 @@ import ( "github.com/systemli/ticker/internal/storage" ) -func PrefetchUser(s storage.TickerStorage) gin.HandlerFunc { +func PrefetchUser(s storage.Storage) gin.HandlerFunc { return func(c *gin.Context) { userID, err := strconv.Atoi(c.Param("userID")) if err != nil { diff --git a/internal/bridge/bridge.go b/internal/bridge/bridge.go index 82e7f6e9..b0495ce1 100644 --- a/internal/bridge/bridge.go +++ b/internal/bridge/bridge.go @@ -15,7 +15,7 @@ type Bridge interface { type Bridges map[string]Bridge -func RegisterBridges(config config.Config, storage storage.TickerStorage) Bridges { +func RegisterBridges(config config.Config, storage storage.Storage) Bridges { telegram := TelegramBridge{config, storage} mastodon := MastodonBridge{config, storage} diff --git a/internal/bridge/mastodon.go b/internal/bridge/mastodon.go index cc56141e..123f209e 100644 --- a/internal/bridge/mastodon.go +++ b/internal/bridge/mastodon.go @@ -11,7 +11,7 @@ import ( type MastodonBridge struct { config config.Config - storage storage.TickerStorage + storage storage.Storage } func (mb *MastodonBridge) Send(ticker storage.Ticker, message *storage.Message) error { diff --git a/internal/bridge/telegram.go b/internal/bridge/telegram.go index c4a00040..6170014e 100644 --- a/internal/bridge/telegram.go +++ b/internal/bridge/telegram.go @@ -8,7 +8,7 @@ import ( type TelegramBridge struct { config config.Config - storage storage.TickerStorage + storage storage.Storage } func (tb *TelegramBridge) Send(ticker storage.Ticker, message *storage.Message) error { diff --git a/internal/storage/db.go b/internal/storage/db.go deleted file mode 100644 index 3eddc6be..00000000 --- a/internal/storage/db.go +++ /dev/null @@ -1,13 +0,0 @@ -package storage - -import "github.com/asdine/storm" - -//OpenDB returns a storm.DB reference -func OpenDB(path string) *storm.DB { - db, err := storm.Open(path) - if err != nil { - log.WithError(err).Panic("failed to open database file") - } - - return db -} diff --git a/internal/storage/storage.go b/internal/storage/storage.go index ed744272..fa88fc30 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -1,17 +1,13 @@ package storage import ( - "os" - - "github.com/asdine/storm" - "github.com/asdine/storm/q" "github.com/sirupsen/logrus" "github.com/systemli/ticker/internal/api/pagination" ) var log = logrus.WithField("package", "storage") -type TickerStorage interface { +type Storage interface { CountUser() (int, error) FindUsers() ([]User, error) FindUserByID(id int) (User, error) @@ -48,351 +44,3 @@ type TickerStorage interface { FindUploadsByIDs(ids []int) ([]Upload, error) UploadPath() string } - -type Storage struct { - db *storm.DB - uploadPath string -} - -func NewStorage(storagePath, uploadPath string) *Storage { - return &Storage{ - db: OpenDB(storagePath), - uploadPath: uploadPath, - } -} - -func (s *Storage) CountUser() (int, error) { - return s.db.Count(&User{}) -} - -func (s *Storage) FindUsers() ([]User, error) { - users := make([]User, 0) - err := s.db.Select().Reverse().Find(&users) - if err != nil && err.Error() != "not found" { - return users, err - } - - return users, nil -} - -func (s *Storage) FindUserByID(id int) (User, error) { - var user User - - err := s.db.One("ID", id, &user) - - return user, err -} - -func (s *Storage) FindUsersByTicker(ticker Ticker) ([]User, error) { - users := make([]User, 0) - err := s.db.Select().Each(new(User), func(record interface{}) error { - u := record.(*User) - - for _, id := range u.Tickers { - if id == ticker.ID { - users = append(users, *u) - } - } - - return nil - }) - - if err != nil { - return users, err - } - - return users, nil -} - -func (s *Storage) FindUserByEmail(email string) (User, error) { - var user User - - err := s.db.One("Email", email, &user) - return user, err -} - -func (s *Storage) SaveUser(user *User) error { - return s.db.Save(user) -} - -func (s *Storage) DeleteUser(user User) error { - return s.db.DeleteStruct(&user) -} - -func (s *Storage) AddUsersToTicker(ticker Ticker, ids []int) error { - users := make([]User, 0) - err := s.db.Select(q.In("ID", ids)).Find(&users) - if err != nil { - return err - } - - for _, user := range users { - if user.IsSuperAdmin { - continue - } - user.AddTicker(ticker) - err = s.SaveUser(&user) - } - - return err -} - -func (s *Storage) RemoveTickerFromUser(ticker Ticker, user User) error { - user.RemoveTicker(ticker) - - return s.SaveUser(&user) -} - -func (s *Storage) FindTickers() ([]Ticker, error) { - tickers := make([]Ticker, 0) - - err := s.db.Select().Reverse().Find(&tickers) - if err != nil && err.Error() != "not found" { - return tickers, err - } - - return tickers, nil -} - -func (s *Storage) FindTickersByIDs(ids []int) ([]Ticker, error) { - tickers := make([]Ticker, 0) - - err := s.db.Select(q.In("ID", ids)).Reverse().Find(&tickers) - if err != nil && err.Error() != "not found" { - return tickers, err - } - - return tickers, nil -} - -func (s *Storage) FindTickerByDomain(domain string) (Ticker, error) { - var ticker Ticker - - err := s.db.One("Domain", domain, &ticker) - if err != nil { - return ticker, err - } - - return ticker, nil -} - -func (s *Storage) FindTickerByID(id int) (Ticker, error) { - var ticker Ticker - - err := s.db.One("ID", id, &ticker) - if err != nil { - return ticker, err - } - - return ticker, nil -} - -func (s *Storage) SaveTicker(ticker *Ticker) error { - return s.db.Save(ticker) -} - -func (s *Storage) DeleteTicker(ticker Ticker) error { - return s.db.DeleteStruct(&ticker) -} - -func (s *Storage) FindUploadsByMessage(message Message) []Upload { - uploads := make([]Upload, 0) - - if len(message.Attachments) > 0 { - var uuids []string - for _, attachment := range message.Attachments { - uuids = append(uuids, attachment.UUID) - } - err := s.db.Select(q.In("UUID", uuids)).Find(&uploads) - if err != nil { - log.WithError(err).Error("failed to find uploads for message") - } - } - - return uploads -} - -func (s *Storage) FindUploadByUUID(uuid string) (Upload, error) { - var upload Upload - err := s.db.One("UUID", uuid, &upload) - return upload, err -} - -func (s *Storage) FindUploadsByIDs(ids []int) ([]Upload, error) { - uploads := make([]Upload, 0) - err := s.db.Select(q.In("ID", ids)).Find(&uploads) - return uploads, err -} - -func (s *Storage) UploadPath() string { - return s.uploadPath -} - -func (s *Storage) SaveUpload(upload *Upload) error { - return s.db.Save(upload) -} - -func (s *Storage) DeleteUpload(upload Upload) error { - var err error - //TODO: Rework with afero.FS from Config - if err = os.Remove(upload.FullPath(s.uploadPath)); err != nil { - log.WithError(err).WithField("upload", upload).Error("failed to delete upload file") - } - - if err = s.db.DeleteStruct(&upload); err != nil { - log.WithError(err).WithField("upload", upload).Error("failed to delete upload") - } - - return err -} - -func (s *Storage) DeleteUploads(uploads []Upload) { - for _, upload := range uploads { - err := s.DeleteUpload(upload) - if err != nil { - log.WithError(err).WithFields(logrus.Fields{"id": upload.ID, "uuid": upload.UUID}).Error("failed to delete upload") - } - } -} - -func (s *Storage) DeleteUploadsByTicker(ticker Ticker) error { - err := s.db.Select(q.Eq("TickerID", ticker.ID)).Delete(&Upload{}) - if err != nil && err.Error() == "not found" { - return nil - } - - return err -} - -func (s *Storage) FindMessage(tickerID, messageID int) (Message, error) { - var message Message - matcher := q.And(q.Eq("ID", messageID), q.Eq("Ticker", tickerID)) - err := s.db.Select(matcher).First(&message) - return message, err -} - -func (s *Storage) FindMessagesByTicker(ticker Ticker) ([]Message, error) { - messages := make([]Message, 0) - - err := s.db.Select(q.Eq("Ticker", ticker.ID)).Reverse().Find(&messages) - if err != nil && err.Error() == "not found" { - return messages, nil - } - return messages, err -} - -func (s *Storage) FindMessagesByTickerAndPagination(ticker Ticker, pagination pagination.Pagination) ([]Message, error) { - messages := make([]Message, 0) - - matcher := q.Eq("Ticker", ticker.ID) - if pagination.GetBefore() != 0 { - matcher = q.And(q.Eq("Ticker", ticker.ID), q.Lt("ID", pagination.GetBefore())) - } - if pagination.GetAfter() != 0 { - matcher = q.And(q.Eq("Ticker", ticker.ID), q.Gt("ID", pagination.GetAfter())) - } - - err := s.db.Select(matcher).OrderBy("CreationDate").Limit(pagination.GetLimit()).Reverse().Find(&messages) - if err != nil && err.Error() == "not found" { - return messages, nil - } - return messages, err -} - -func (s *Storage) SaveMessage(message *Message) error { - return s.db.Save(message) -} - -func (s *Storage) DeleteMessage(message Message) error { - uploads := s.FindUploadsByMessage(message) - - if len(uploads) > 0 { - s.DeleteUploads(uploads) - } - - return s.db.DeleteStruct(&message) -} - -func (s *Storage) DeleteMessages(ticker Ticker) error { - var messages []Message - if err := s.db.Find("Ticker", ticker.ID, &messages); err != nil { - log.WithField("error", err).WithField("ticker", ticker.ID).Error("failed find messages for ticker") - return err - } - - for _, message := range messages { - _ = s.DeleteMessage(message) - } - - return nil -} - -func (s *Storage) FindSetting(name string) (Setting, error) { - var setting Setting - err := s.db.One("Name", name, &setting) - if err != nil && err.Error() == "not found" { - return setting, err - } - - return setting, nil -} - -func (s *Storage) GetInactiveSetting() Setting { - setting, err := s.FindSetting(SettingInactiveName) - if err != nil { - return DefaultInactiveSetting() - } - - return setting -} - -func (s *Storage) GetRefreshIntervalSetting() Setting { - setting, err := s.FindSetting(SettingRefreshInterval) - if err != nil { - return DefaultRefreshIntervalSetting() - } - - return setting -} - -func (s *Storage) GetRefreshIntervalSettingValue() int { - setting := s.GetRefreshIntervalSetting() - - var value int - switch sv := setting.Value.(type) { - case float64: - value = int(sv) - default: - value = sv.(int) - } - - return value -} - -func (s *Storage) SaveInactiveSetting(inactiveSettings InactiveSettings) error { - setting, err := s.FindSetting(SettingInactiveName) - if err != nil { - setting = Setting{Name: SettingInactiveName, Value: inactiveSettings} - } else { - setting.Value = inactiveSettings - } - - return s.db.Save(&setting) -} - -func (s *Storage) SaveRefreshInterval(refreshInterval float64) error { - setting, err := s.FindSetting(SettingRefreshInterval) - if err != nil { - setting = Setting{Name: SettingRefreshInterval, Value: refreshInterval} - } else { - setting.Value = refreshInterval - } - return s.db.Save(&setting) -} - -func (s *Storage) DropAll() { - _ = s.db.Drop("User") - _ = s.db.Drop("Message") - _ = s.db.Drop("Ticker") - _ = s.db.Drop("Setting") -} diff --git a/internal/storage/storm_storage.go b/internal/storage/storm_storage.go new file mode 100644 index 00000000..abc23422 --- /dev/null +++ b/internal/storage/storm_storage.go @@ -0,0 +1,367 @@ +package storage + +import ( + "os" + + "github.com/asdine/storm" + "github.com/asdine/storm/q" + "github.com/sirupsen/logrus" + "github.com/systemli/ticker/internal/api/pagination" +) + +type StormStorage struct { + db *storm.DB + uploadPath string +} + +func OpenDB(path string) *storm.DB { + db, err := storm.Open(path) + if err != nil { + log.WithError(err).Panic("failed to open database file") + } + + return db +} + +func NewStormStorage(storagePath, uploadPath string) *StormStorage { + return &StormStorage{ + db: OpenDB(storagePath), + uploadPath: uploadPath, + } +} + +func (s *StormStorage) CountUser() (int, error) { + return s.db.Count(&User{}) +} + +func (s *StormStorage) FindUsers() ([]User, error) { + users := make([]User, 0) + err := s.db.Select().Reverse().Find(&users) + if err != nil && err.Error() != "not found" { + return users, err + } + + return users, nil +} + +func (s *StormStorage) FindUserByID(id int) (User, error) { + var user User + + err := s.db.One("ID", id, &user) + + return user, err +} + +func (s *StormStorage) FindUsersByTicker(ticker Ticker) ([]User, error) { + users := make([]User, 0) + err := s.db.Select().Each(new(User), func(record interface{}) error { + u := record.(*User) + + for _, id := range u.Tickers { + if id == ticker.ID { + users = append(users, *u) + } + } + + return nil + }) + + if err != nil { + return users, err + } + + return users, nil +} + +func (s *StormStorage) FindUserByEmail(email string) (User, error) { + var user User + + err := s.db.One("Email", email, &user) + return user, err +} + +func (s *StormStorage) SaveUser(user *User) error { + return s.db.Save(user) +} + +func (s *StormStorage) DeleteUser(user User) error { + return s.db.DeleteStruct(&user) +} + +func (s *StormStorage) AddUsersToTicker(ticker Ticker, ids []int) error { + users := make([]User, 0) + err := s.db.Select(q.In("ID", ids)).Find(&users) + if err != nil { + return err + } + + for _, user := range users { + if user.IsSuperAdmin { + continue + } + user.AddTicker(ticker) + err = s.SaveUser(&user) + } + + return err +} + +func (s *StormStorage) RemoveTickerFromUser(ticker Ticker, user User) error { + user.RemoveTicker(ticker) + + return s.SaveUser(&user) +} + +func (s *StormStorage) FindTickers() ([]Ticker, error) { + tickers := make([]Ticker, 0) + + err := s.db.Select().Reverse().Find(&tickers) + if err != nil && err.Error() != "not found" { + return tickers, err + } + + return tickers, nil +} + +func (s *StormStorage) FindTickersByIDs(ids []int) ([]Ticker, error) { + tickers := make([]Ticker, 0) + + err := s.db.Select(q.In("ID", ids)).Reverse().Find(&tickers) + if err != nil && err.Error() != "not found" { + return tickers, err + } + + return tickers, nil +} + +func (s *StormStorage) FindTickerByDomain(domain string) (Ticker, error) { + var ticker Ticker + + err := s.db.One("Domain", domain, &ticker) + if err != nil { + return ticker, err + } + + return ticker, nil +} + +func (s *StormStorage) FindTickerByID(id int) (Ticker, error) { + var ticker Ticker + + err := s.db.One("ID", id, &ticker) + if err != nil { + return ticker, err + } + + return ticker, nil +} + +func (s *StormStorage) SaveTicker(ticker *Ticker) error { + return s.db.Save(ticker) +} + +func (s *StormStorage) DeleteTicker(ticker Ticker) error { + return s.db.DeleteStruct(&ticker) +} + +func (s *StormStorage) FindUploadsByMessage(message Message) []Upload { + uploads := make([]Upload, 0) + + if len(message.Attachments) > 0 { + var uuids []string + for _, attachment := range message.Attachments { + uuids = append(uuids, attachment.UUID) + } + err := s.db.Select(q.In("UUID", uuids)).Find(&uploads) + if err != nil { + log.WithError(err).Error("failed to find uploads for message") + } + } + + return uploads +} + +func (s *StormStorage) FindUploadByUUID(uuid string) (Upload, error) { + var upload Upload + err := s.db.One("UUID", uuid, &upload) + return upload, err +} + +func (s *StormStorage) FindUploadsByIDs(ids []int) ([]Upload, error) { + uploads := make([]Upload, 0) + err := s.db.Select(q.In("ID", ids)).Find(&uploads) + return uploads, err +} + +func (s *StormStorage) UploadPath() string { + return s.uploadPath +} + +func (s *StormStorage) SaveUpload(upload *Upload) error { + return s.db.Save(upload) +} + +func (s *StormStorage) DeleteUpload(upload Upload) error { + var err error + //TODO: Rework with afero.FS from Config + if err = os.Remove(upload.FullPath(s.uploadPath)); err != nil { + log.WithError(err).WithField("upload", upload).Error("failed to delete upload file") + } + + if err = s.db.DeleteStruct(&upload); err != nil { + log.WithError(err).WithField("upload", upload).Error("failed to delete upload") + } + + return err +} + +func (s *StormStorage) DeleteUploads(uploads []Upload) { + for _, upload := range uploads { + err := s.DeleteUpload(upload) + if err != nil { + log.WithError(err).WithFields(logrus.Fields{"id": upload.ID, "uuid": upload.UUID}).Error("failed to delete upload") + } + } +} + +func (s *StormStorage) DeleteUploadsByTicker(ticker Ticker) error { + err := s.db.Select(q.Eq("TickerID", ticker.ID)).Delete(&Upload{}) + if err != nil && err.Error() == "not found" { + return nil + } + + return err +} + +func (s *StormStorage) FindMessage(tickerID, messageID int) (Message, error) { + var message Message + matcher := q.And(q.Eq("ID", messageID), q.Eq("Ticker", tickerID)) + err := s.db.Select(matcher).First(&message) + return message, err +} + +func (s *StormStorage) FindMessagesByTicker(ticker Ticker) ([]Message, error) { + messages := make([]Message, 0) + + err := s.db.Select(q.Eq("Ticker", ticker.ID)).Reverse().Find(&messages) + if err != nil && err.Error() == "not found" { + return messages, nil + } + return messages, err +} + +func (s *StormStorage) FindMessagesByTickerAndPagination(ticker Ticker, pagination pagination.Pagination) ([]Message, error) { + messages := make([]Message, 0) + + matcher := q.Eq("Ticker", ticker.ID) + if pagination.GetBefore() != 0 { + matcher = q.And(q.Eq("Ticker", ticker.ID), q.Lt("ID", pagination.GetBefore())) + } + if pagination.GetAfter() != 0 { + matcher = q.And(q.Eq("Ticker", ticker.ID), q.Gt("ID", pagination.GetAfter())) + } + + err := s.db.Select(matcher).OrderBy("CreationDate").Limit(pagination.GetLimit()).Reverse().Find(&messages) + if err != nil && err.Error() == "not found" { + return messages, nil + } + return messages, err +} + +func (s *StormStorage) SaveMessage(message *Message) error { + return s.db.Save(message) +} + +func (s *StormStorage) DeleteMessage(message Message) error { + uploads := s.FindUploadsByMessage(message) + + if len(uploads) > 0 { + s.DeleteUploads(uploads) + } + + return s.db.DeleteStruct(&message) +} + +func (s *StormStorage) DeleteMessages(ticker Ticker) error { + var messages []Message + if err := s.db.Find("Ticker", ticker.ID, &messages); err != nil { + log.WithField("error", err).WithField("ticker", ticker.ID).Error("failed find messages for ticker") + return err + } + + for _, message := range messages { + _ = s.DeleteMessage(message) + } + + return nil +} + +func (s *StormStorage) FindSetting(name string) (Setting, error) { + var setting Setting + err := s.db.One("Name", name, &setting) + if err != nil && err.Error() == "not found" { + return setting, err + } + + return setting, nil +} + +func (s *StormStorage) GetInactiveSetting() Setting { + setting, err := s.FindSetting(SettingInactiveName) + if err != nil { + return DefaultInactiveSetting() + } + + return setting +} + +func (s *StormStorage) GetRefreshIntervalSetting() Setting { + setting, err := s.FindSetting(SettingRefreshInterval) + if err != nil { + return DefaultRefreshIntervalSetting() + } + + return setting +} + +func (s *StormStorage) GetRefreshIntervalSettingValue() int { + setting := s.GetRefreshIntervalSetting() + + var value int + switch sv := setting.Value.(type) { + case float64: + value = int(sv) + default: + value = sv.(int) + } + + return value +} + +func (s *StormStorage) SaveInactiveSetting(inactiveSettings InactiveSettings) error { + setting, err := s.FindSetting(SettingInactiveName) + if err != nil { + setting = Setting{Name: SettingInactiveName, Value: inactiveSettings} + } else { + setting.Value = inactiveSettings + } + + return s.db.Save(&setting) +} + +func (s *StormStorage) SaveRefreshInterval(refreshInterval float64) error { + setting, err := s.FindSetting(SettingRefreshInterval) + if err != nil { + setting = Setting{Name: SettingRefreshInterval, Value: refreshInterval} + } else { + setting.Value = refreshInterval + } + return s.db.Save(&setting) +} + +func (s *StormStorage) DropAll() { + _ = s.db.Drop("User") + _ = s.db.Drop("Message") + _ = s.db.Drop("Ticker") + _ = s.db.Drop("Setting") +} diff --git a/internal/storage/storage_test.go b/internal/storage/storm_storage_test.go similarity index 99% rename from internal/storage/storage_test.go rename to internal/storage/storm_storage_test.go index ae1386c5..a13c24cb 100644 --- a/internal/storage/storage_test.go +++ b/internal/storage/storm_storage_test.go @@ -22,7 +22,7 @@ func TestStorage(t *testing.T) { var _ = Describe("Storage", func() { var storagePath = fmt.Sprintf("%s/storage_%d.db", strings.TrimSuffix(os.TempDir(), "/"), time.Now().Unix()) - var storage = NewStorage(storagePath, "/uploads") + var storage = NewStormStorage(storagePath, "/uploads") BeforeEach(func() { storage.DropAll()