diff --git a/go.mod b/go.mod index 7c65a8c..1cadaf5 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/jarcoal/httpmock v1.3.1 github.com/lib/pq v1.10.7 github.com/mattn/go-sqlite3 v1.14.9 + github.com/pressly/goose/v3 v3.22.1 github.com/prometheus/client_golang v1.19.0 github.com/rs/zerolog v1.33.0 github.com/spf13/cobra v1.8.1 @@ -117,6 +118,7 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mfridman/interpolate v0.0.2 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect @@ -135,6 +137,7 @@ require ( github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sethvargo/go-retry v0.3.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.7.0 // indirect @@ -149,12 +152,12 @@ require ( go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // indirect diff --git a/go.sum b/go.sum index bc4263c..f831787 100644 --- a/go.sum +++ b/go.sum @@ -678,6 +678,8 @@ github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= +github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= +github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= @@ -718,6 +720,8 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= @@ -781,6 +785,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/pressly/goose/v3 v3.22.1 h1:2zICEfr1O3yTP9BRZMGPj7qFxQ+ik6yeo+z1LMuioLc= +github.com/pressly/goose/v3 v3.22.1/go.mod h1:xtMpbstWyCpyH+0cxLTMCENWBG+0CSxvTsXhW95d5eo= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -819,6 +825,8 @@ github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43Z github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -844,6 +852,8 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= +github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -949,12 +959,12 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -988,8 +998,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1074,8 +1084,8 @@ golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1211,13 +1221,13 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1228,8 +1238,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1545,6 +1555,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/sqlite v1.33.0 h1:WWkA/T2G17okiLGgKAj4/RMIvgyMT19yQ038160IeYk= +modernc.org/sqlite v1.33.0/go.mod h1:9uQ9hF/pCZoYZK73D/ud5Z7cIRIILSZI8NdIemVMTX8= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= diff --git a/sql/01-blocks.sql b/migrations/postgres/01_add_blocks.sql similarity index 82% rename from sql/01-blocks.sql rename to migrations/postgres/01_add_blocks.sql index 7b66724..8b8be98 100644 --- a/sql/01-blocks.sql +++ b/migrations/postgres/01_add_blocks.sql @@ -1,3 +1,4 @@ +-- +goose Up CREATE TABLE IF NOT EXISTS blocks ( chain TEXT not null, height BIGINT NOT NULL, @@ -6,4 +7,7 @@ CREATE TABLE IF NOT EXISTS blocks ( signatures TEXT NOT NULL, validators TEXT NOT NULL, PRIMARY KEY (chain, height) -); \ No newline at end of file +); + +-- +goose Down +DROP TABLE blocks; diff --git a/sql/02-notifiers.sql b/migrations/postgres/02_add_notifiers.sql similarity index 81% rename from sql/02-notifiers.sql rename to migrations/postgres/02_add_notifiers.sql index 6528e58..751ab65 100644 --- a/sql/02-notifiers.sql +++ b/migrations/postgres/02_add_notifiers.sql @@ -1,3 +1,4 @@ +-- +goose Up CREATE TABLE IF NOT EXISTS notifiers ( chain TEXT NOT NULL, reporter TEXT NOT NULL, @@ -5,4 +6,7 @@ CREATE TABLE IF NOT EXISTS notifiers ( user_name TEXT NOT NULL, user_id TEXT NOT NULL, PRIMARY KEY (chain, reporter, operator_address, user_id) -); \ No newline at end of file +); + +-- +goose Down +DROP TABLE notifiers; diff --git a/sql/03-data.sql b/migrations/postgres/03_add_data.sql similarity index 73% rename from sql/03-data.sql rename to migrations/postgres/03_add_data.sql index d03c546..ee923e9 100644 --- a/sql/03-data.sql +++ b/migrations/postgres/03_add_data.sql @@ -1,6 +1,10 @@ +-- +goose Up CREATE TABLE IF NOT EXISTS data ( chain TEXT NOT NULL, key TEXT NOT NULL, value TEXT NOT NULL, PRIMARY KEY (chain, key) -); \ No newline at end of file +); + +-- +goose Down +DROP TABLE data; diff --git a/sql/04-events.postgres.sql b/migrations/postgres/04_add_events.sql similarity index 81% rename from sql/04-events.postgres.sql rename to migrations/postgres/04_add_events.sql index 453759a..19679a1 100644 --- a/sql/04-events.postgres.sql +++ b/migrations/postgres/04_add_events.sql @@ -1,3 +1,4 @@ +-- +goose Up CREATE TABLE IF NOT EXISTS events ( id SERIAL PRIMARY KEY, chain TEXT NOT NULL, @@ -6,4 +7,7 @@ CREATE TABLE IF NOT EXISTS events ( validator TEXT NOT NULL, payload TEXT NOT NULL, time TIMESTAMP NOT NULL -); \ No newline at end of file +); + +-- +goose Down +DROP TABLE events; diff --git a/migrations/postgres/migrations.go b/migrations/postgres/migrations.go new file mode 100644 index 0000000..d350da9 --- /dev/null +++ b/migrations/postgres/migrations.go @@ -0,0 +1,6 @@ +package postgres + +import "embed" + +//go:embed **.sql +var EmbedFS embed.FS diff --git a/migrations/sqlite/01_add_blocks.sql b/migrations/sqlite/01_add_blocks.sql new file mode 100644 index 0000000..8b8be98 --- /dev/null +++ b/migrations/sqlite/01_add_blocks.sql @@ -0,0 +1,13 @@ +-- +goose Up +CREATE TABLE IF NOT EXISTS blocks ( + chain TEXT not null, + height BIGINT NOT NULL, + time BIGINT NOT NULL, + proposer TEXT NOT NULL, + signatures TEXT NOT NULL, + validators TEXT NOT NULL, + PRIMARY KEY (chain, height) +); + +-- +goose Down +DROP TABLE blocks; diff --git a/migrations/sqlite/02_add_notifiers.sql b/migrations/sqlite/02_add_notifiers.sql new file mode 100644 index 0000000..751ab65 --- /dev/null +++ b/migrations/sqlite/02_add_notifiers.sql @@ -0,0 +1,12 @@ +-- +goose Up +CREATE TABLE IF NOT EXISTS notifiers ( + chain TEXT NOT NULL, + reporter TEXT NOT NULL, + operator_address TEXT NOT NULL, + user_name TEXT NOT NULL, + user_id TEXT NOT NULL, + PRIMARY KEY (chain, reporter, operator_address, user_id) +); + +-- +goose Down +DROP TABLE notifiers; diff --git a/migrations/sqlite/03_add_data.sql b/migrations/sqlite/03_add_data.sql new file mode 100644 index 0000000..ee923e9 --- /dev/null +++ b/migrations/sqlite/03_add_data.sql @@ -0,0 +1,10 @@ +-- +goose Up +CREATE TABLE IF NOT EXISTS data ( + chain TEXT NOT NULL, + key TEXT NOT NULL, + value TEXT NOT NULL, + PRIMARY KEY (chain, key) +); + +-- +goose Down +DROP TABLE data; diff --git a/migrations/sqlite/04_add_events.sql b/migrations/sqlite/04_add_events.sql new file mode 100644 index 0000000..482e0b5 --- /dev/null +++ b/migrations/sqlite/04_add_events.sql @@ -0,0 +1,13 @@ +-- +goose Up +CREATE TABLE IF NOT EXISTS events ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + chain TEXT NOT NULL, + height BIGINT NOT NULL, + event TEXT NOT NULL, + validator TEXT NOT NULL, + payload TEXT NOT NULL, + time TEXT NOT NULL +); + +-- +goose Down +DROP TABLE events; diff --git a/migrations/sqlite/migrations.go b/migrations/sqlite/migrations.go new file mode 100644 index 0000000..d350da9 --- /dev/null +++ b/migrations/sqlite/migrations.go @@ -0,0 +1,6 @@ +package postgres + +import "embed" + +//go:embed **.sql +var EmbedFS embed.FS diff --git a/pkg/database/client.go b/pkg/database/client.go index 02483dc..ad47371 100644 --- a/pkg/database/client.go +++ b/pkg/database/client.go @@ -1,10 +1,33 @@ package database -import "database/sql" +import ( + "database/sql" + "strings" + + "github.com/rs/zerolog" +) + +type DatabaseLogger struct { + Logger zerolog.Logger +} + +func NewDatabaseLogger(logger zerolog.Logger) *DatabaseLogger { + return &DatabaseLogger{ + Logger: logger.With().Str("component", "database_migrations").Logger(), + } +} + +func (l *DatabaseLogger) Printf(format string, v ...interface{}) { + l.Logger.Info().Msgf(strings.TrimSpace(format), v...) +} + +func (l *DatabaseLogger) Fatalf(format string, v ...interface{}) { + l.Logger.Panic().Msgf(strings.TrimSpace(format), v...) +} type DatabaseClient interface { Exec(query string, args ...any) (sql.Result, error) Query(query string, args ...any) (*sql.Rows, error) QueryRow(query string, args ...any) *sql.Row - Prepare(query string) (*sql.Stmt, error) + Migrate() error } diff --git a/pkg/database/database.go b/pkg/database/database.go index f8fda3c..819cb55 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -6,7 +6,6 @@ import ( "main/pkg/constants" snapshotPkg "main/pkg/snapshot" "main/pkg/types" - migrationsPkg "main/sql" "sync" "time" @@ -33,47 +32,18 @@ func NewDatabase( func (d *Database) Init() { var db DatabaseClient - var migrations []string switch d.config.Type { case constants.DatabaseTypeSqlite: db = d.InitSqliteDatabase() - migrations = d.GetSqliteMigrations() case constants.DatabaseTypePostgres: db = d.InitPostgresDatabase() - migrations = d.GetPostgresMigrations() default: - d.logger.Fatal().Str("type", d.config.Type).Msg("Unsupported database type") + d.logger.Panic().Str("type", d.config.Type).Msg("Unsupported database type") } - for _, entry := range migrations { - d.logger.Info(). - Str("name", entry). - Msg("Applying sqlite migration") - - content, err := migrationsPkg.FS.ReadFile(entry) - if err != nil { - d.logger.Fatal(). - Str("name", entry). - Err(err). - Msg("Could not read migration content") - } - - statement, err := db.Prepare(string(content)) - if err != nil { - d.logger.Fatal(). - Str("name", entry). - Err(err). - Msg("Could not prepare migration") - } - if _, err := statement.Exec(); err != nil { - d.logger.Fatal(). - Str("name", entry). - Err(err). - Msg("Could not execute migration") - } - - statement.Close() //nolint:all + if err := db.Migrate(); err != nil { + d.logger.Panic().Err(err).Msg("Failed to migrate database") } d.client = db diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index c831863..5677798 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -2,12 +2,15 @@ package database import ( "database/sql" + postgresMigrations "main/migrations/postgres" _ "github.com/lib/pq" + "github.com/pressly/goose/v3" ) type PostgresDatabaseClient struct { - db *sql.DB + db *sql.DB + logger *DatabaseLogger } func (d *Database) InitPostgresDatabase() DatabaseClient { @@ -29,16 +32,7 @@ func (d *Database) InitPostgresDatabase() DatabaseClient { Str("path", d.config.Path). Msg("PostgreSQL database connected") - return &PostgresDatabaseClient{db: db} -} - -func (d *Database) GetPostgresMigrations() []string { - return []string{ - "01-blocks.sql", - "02-notifiers.sql", - "03-data.sql", - "04-events.postgres.sql", - } + return &PostgresDatabaseClient{db: db, logger: NewDatabaseLogger(d.logger)} } func (d *PostgresDatabaseClient) Exec(query string, args ...any) (sql.Result, error) { @@ -49,10 +43,15 @@ func (d *PostgresDatabaseClient) Query(query string, args ...any) (*sql.Rows, er return d.db.Query(query, args...) } -func (d *PostgresDatabaseClient) Prepare(query string) (*sql.Stmt, error) { - return d.db.Prepare(query) -} - func (d *PostgresDatabaseClient) QueryRow(query string, args ...any) *sql.Row { return d.db.QueryRow(query, args...) } + +func (d *PostgresDatabaseClient) Migrate() error { + goose.SetBaseFS(postgresMigrations.EmbedFS) + goose.SetLogger(d.logger) + + _ = goose.SetDialect("postgres") + + return goose.Up(d.db, ".") +} diff --git a/pkg/database/sqlite.go b/pkg/database/sqlite.go index 8e31a9b..406d41e 100644 --- a/pkg/database/sqlite.go +++ b/pkg/database/sqlite.go @@ -2,10 +2,14 @@ package database import ( "database/sql" + sqliteMigrations "main/migrations/sqlite" + + "github.com/pressly/goose/v3" ) type SqliteDatabaseClient struct { - db *sql.DB + db *sql.DB + logger *DatabaseLogger } func (d *Database) InitSqliteDatabase() DatabaseClient { @@ -27,16 +31,7 @@ func (d *Database) InitSqliteDatabase() DatabaseClient { Str("path", d.config.Path). Msg("SQLite database connected") - return &SqliteDatabaseClient{db: db} -} - -func (d *Database) GetSqliteMigrations() []string { - return []string{ - "01-blocks.sql", - "02-notifiers.sql", - "03-data.sql", - "04-events.sqlite.sql", - } + return &SqliteDatabaseClient{db: db, logger: NewDatabaseLogger(d.logger)} } func (d *SqliteDatabaseClient) Exec(query string, args ...any) (sql.Result, error) { @@ -47,10 +42,15 @@ func (d *SqliteDatabaseClient) Query(query string, args ...any) (*sql.Rows, erro return d.db.Query(query, args...) } -func (d *SqliteDatabaseClient) Prepare(query string) (*sql.Stmt, error) { - return d.db.Prepare(query) -} - func (d *SqliteDatabaseClient) QueryRow(query string, args ...any) *sql.Row { return d.db.QueryRow(query, args...) } + +func (d *SqliteDatabaseClient) Migrate() error { + goose.SetBaseFS(sqliteMigrations.EmbedFS) + goose.SetLogger(d.logger) + + _ = goose.SetDialect("sqlite") + + return goose.Up(d.db, ".") +} diff --git a/sql/04-events.sqlite.sql b/sql/04-events.sqlite.sql deleted file mode 100644 index 1cdb47a..0000000 --- a/sql/04-events.sqlite.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE IF NOT EXISTS events ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - chain TEXT NOT NULL, - height BIGINT NOT NULL, - event TEXT NOT NULL, - validator TEXT NOT NULL, - payload TEXT NOT NULL, - time TEXT NOT NULL -); \ No newline at end of file diff --git a/sql/sql.go b/sql/sql.go deleted file mode 100644 index 1b208b6..0000000 --- a/sql/sql.go +++ /dev/null @@ -1,6 +0,0 @@ -package sql - -import "embed" - -//go:embed *.sql -var FS embed.FS