summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--assets/style.css8
-rw-r--r--cmd/start.go10
-rw-r--r--components/actions_table.html17
-rw-r--r--config/config.go1
-rw-r--r--go.mod21
-rw-r--r--go.sum68
-rw-r--r--internal/database/migrations/001_init.down.sql4
-rw-r--r--internal/database/migrations/001_init.up.sql24
-rw-r--r--internal/database/migrations/init.go3
-rw-r--r--internal/database/migrations/migrations.bindata.go267
-rw-r--r--internal/database/repos/main.go15
-rw-r--r--internal/database/sql/main.go141
-rw-r--r--internal/handlers/main.go25
-rw-r--r--internal/models/models.go4
-rw-r--r--internal/server/main.go8
-rw-r--r--internal/service/main.go0
17 files changed, 589 insertions, 30 deletions
diff --git a/Makefile b/Makefile
index 2c4102c..450ff6c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,6 @@
.PHONY: all init deps install test lint run stop
run:
- # templ generate
go build
./apjournal start
@@ -33,4 +32,4 @@ stop-container:
docker rm -f apjournal 2>/dev/null && echo "old container removed"
run-container: stop-container
- docker run --name=apjournal -v $(CURDIR)/store.json:/root/store.json -p 0.0.0.0:8087:8087 -d apjournal:master
+ docker run --name=apjournal -v $(CURDIR)/store.json:/root/store.json -p 0.0.0.0:9000:9000 -d apjournal:master
diff --git a/assets/style.css b/assets/style.css
index 821a499..5d2f089 100644
--- a/assets/style.css
+++ b/assets/style.css
@@ -33,3 +33,11 @@ tr{
display: inline flow-root;
margin-inline: 10px;
}
+.action_name{
+ border: none;
+ display: inline;
+ font-family: inherit;
+ font-size: inherit;
+ padding: none;
+ width: auto;
+}
diff --git a/cmd/start.go b/cmd/start.go
index 00872aa..a1f051c 100644
--- a/cmd/start.go
+++ b/cmd/start.go
@@ -1,9 +1,10 @@
package cmd
import (
- "os"
"apjournal/config"
+ database "apjournal/internal/database/sql"
"apjournal/internal/server"
+ "os"
"log/slog"
@@ -28,8 +29,11 @@ var startCmd = &cobra.Command{
"path", viper.ConfigFileUsed())
}
cfg := config.LoadConfig(viper.GetViper())
-
- srv := server.NewServer(cfg, log)
+ db, err := database.InitWithMigrate(cfg.DBURI, true)
+ if err != nil {
+ panic(err)
+ }
+ srv := server.NewServer(cfg, log, db.Conn)
// listen for new messages
log.Info("Listening for incoming events")
srv.Listen()
diff --git a/components/actions_table.html b/components/actions_table.html
index f862906..8b151e5 100644
--- a/components/actions_table.html
+++ b/components/actions_table.html
@@ -1,12 +1,12 @@
{{define "UserScore"}}
<table id="usertable">
<tr>
- <th>ID</th>
+ <th>Username</th>
<th>BurnTime</th>
<th>Score</th>
</tr>
<tr>
- <td>{{.ID}}</td>
+ <td>{{.Username}}</td>
<td>{{.BurnTime}}</td>
<td>{{.Score}}</td>
</tr>
@@ -21,13 +21,15 @@
<th>Commit</th>
</tr>
{{range $action := .Actions}}
- {{if and (eq $action.Type "ActionTypePlus") (not $action.Done)}}
+ {{if and (eq $action.Type "ActionTypePlus") (or (not $action.Done) ($action.Repeatable))}}
+ <form hx-post="/done">
<tr>
- <td>{{$action.Name}}</td>
+ <td><input class="action_name" name="name" value={{$action.Name}} type="hidden" readonly />{{$action.Name}}</td>
<td>{{$action.Magnitude}}</td>
<td>{{$action.Repeatable}}</td>
- <td><button>Done it</button></td>
+ <td><input type="submit" value="Done It"></input></td>
</tr>
+ </form>
{{end}}
{{end}}
</table>
@@ -43,12 +45,15 @@
</tr>
{{range $action := .Actions}}
{{if eq $action.Type "ActionTypeMinus"}}
+ <form hx-post="/done">
<tr>
+ <td><input class="action_name" name="name" value={{$action.Name}} type="hidden" readonly />{{$action.Name}}</td>
<td>{{$action.Name}}</td>
<td>{{$action.Magnitude}}</td>
<td>{{$action.Repeatable}}</td>
- <td><button>Done it</button></td>
+ <td><input type="submit" value="Done It"></input></td>
</tr>
+ </form>
{{end}}
{{end}}
</table>
diff --git a/config/config.go b/config/config.go
index 135df95..e2225d8 100644
--- a/config/config.go
+++ b/config/config.go
@@ -11,6 +11,7 @@ type Config struct {
ServerConfig ServerConfig `mapstructure:"SERVICE"`
BaseURL string `mapstructure:"BASE_URL"`
SessionLifetime int `mapstructure:"SESSION_LIFETIME_SECONDS"`
+ DBURI string `mapstructure:"DBURI"`
}
type ServerConfig struct {
diff --git a/go.mod b/go.mod
index 71dd35f..74c317e 100644
--- a/go.mod
+++ b/go.mod
@@ -3,16 +3,32 @@ module apjournal
go 1.22.1
require (
+ github.com/golang-migrate/migrate v3.5.4+incompatible
+ github.com/jackc/pgx/v5 v5.5.5
+ github.com/jmoiron/sqlx v1.3.5
+ github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.18.2
)
require (
+ github.com/distribution/reference v0.6.0 // indirect
+ github.com/docker/docker v26.0.0+incompatible // indirect
+ github.com/docker/go-connections v0.5.0 // indirect
+ github.com/docker/go-units v0.5.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
+ github.com/google/go-cmp v0.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/jackc/pgpassfile v1.0.0 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+ github.com/jackc/puddle/v2 v2.2.1 // indirect
+ github.com/lib/pq v1.2.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
+ github.com/moby/docker-image-spec v1.3.1 // indirect
+ github.com/opencontainers/go-digest v1.0.0 // indirect
+ github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
@@ -20,10 +36,15 @@ require (
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
+ github.com/stretchr/testify v1.9.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 // indirect
+ go.opentelemetry.io/otel/trace v1.25.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
+ golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
+ golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
diff --git a/go.sum b/go.sum
index b6a7dcc..3772a8a 100644
--- a/go.sum
+++ b/go.sum
@@ -1,28 +1,72 @@
+github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
+github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
+github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
+github.com/docker/docker v26.0.0+incompatible h1:Ng2qi+gdKADUa/VM+6b6YaY2nlZhk/lVJiKR/2bMudU=
+github.com/docker/docker v26.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
+github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
+github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
+github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
+github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-migrate/migrate v3.5.4+incompatible h1:R7OzwvCJTCgwapPCiX6DyBiu2czIUMDCB118gFTKTUA=
+github.com/golang-migrate/migrate v3.5.4+incompatible/go.mod h1:IsVUlFN5puWOmXrqjgGUfIRIbU7mr8oNBE2tyERd9Wk=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
+github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
+github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
+github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
+github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
+github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
+github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
+github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -49,25 +93,39 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8=
+go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k=
+go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg=
+go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA=
+go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s=
+go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM=
+go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
+golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
+golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/internal/database/migrations/001_init.down.sql b/internal/database/migrations/001_init.down.sql
new file mode 100644
index 0000000..4b46d47
--- /dev/null
+++ b/internal/database/migrations/001_init.down.sql
@@ -0,0 +1,4 @@
+BEGIN;
+DROP TABLE IF EXISTS user_score;
+DROP TABLE IF EXISTS action;
+COMMIT;
diff --git a/internal/database/migrations/001_init.up.sql b/internal/database/migrations/001_init.up.sql
new file mode 100644
index 0000000..7edbd96
--- /dev/null
+++ b/internal/database/migrations/001_init.up.sql
@@ -0,0 +1,24 @@
+BEGIN;
+CREATE TABLE user_score (
+ id INT GENERATED BY DEFAULT AS IDENTITY,
+ username TEXT UNIQUE NOT NULL,
+ burn_time TIMESTAMP NOT NULL DEFAULT NOW() + interval '1 day',
+ score SMALLINT NOT NULL,
+ created_at timestamp NOT NULL DEFAULT NOW()
+);
+
+CREATE TABLE action (
+ id INT GENERATED BY DEFAULT AS IDENTITY,
+ name TEXT NOT NULL,
+ magnitude SMALLSERIAL NOT NULL DEFAULT 1,
+ repeatable BOOLEAN NOT NULL DEFAULT FALSE,
+ type TEXT NOT NULL,
+ done BOOLEAN NOT NULL DEFAULT FALSE,
+ username TEXT NOT NULL,
+ created_at timestamp NOT NULL DEFAULT NOW(),
+ UNIQUE(username, name),
+ CONSTRAINT fk_user_score
+ FOREIGN KEY(username)
+ REFERENCES user_score(username)
+);
+COMMIT;
diff --git a/internal/database/migrations/init.go b/internal/database/migrations/init.go
new file mode 100644
index 0000000..2b5a212
--- /dev/null
+++ b/internal/database/migrations/init.go
@@ -0,0 +1,3 @@
+package migrations
+
+//go:generate go-bindata -o ./migrations.bindata.go -pkg migrations -ignore=\\*.go ./...
diff --git a/internal/database/migrations/migrations.bindata.go b/internal/database/migrations/migrations.bindata.go
new file mode 100644
index 0000000..8197c0a
--- /dev/null
+++ b/internal/database/migrations/migrations.bindata.go
@@ -0,0 +1,267 @@
+// Code generated for package migrations by go-bindata DO NOT EDIT. (@generated)
+// sources:
+// 001_init.down.sql
+// 001_init.up.sql
+package migrations
+
+import (
+ "bytes"
+ "compress/gzip"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+)
+
+func bindataRead(data []byte, name string) ([]byte, error) {
+ gz, err := gzip.NewReader(bytes.NewBuffer(data))
+ if err != nil {
+ return nil, fmt.Errorf("Read %q: %v", name, err)
+ }
+
+ var buf bytes.Buffer
+ _, err = io.Copy(&buf, gz)
+ clErr := gz.Close()
+
+ if err != nil {
+ return nil, fmt.Errorf("Read %q: %v", name, err)
+ }
+ if clErr != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+}
+
+type asset struct {
+ bytes []byte
+ info os.FileInfo
+}
+
+type bindataFileInfo struct {
+ name string
+ size int64
+ mode os.FileMode
+ modTime time.Time
+}
+
+// Name return file name
+func (fi bindataFileInfo) Name() string {
+ return fi.name
+}
+
+// Size return file size
+func (fi bindataFileInfo) Size() int64 {
+ return fi.size
+}
+
+// Mode return file mode
+func (fi bindataFileInfo) Mode() os.FileMode {
+ return fi.mode
+}
+
+// Mode return file modify time
+func (fi bindataFileInfo) ModTime() time.Time {
+ return fi.modTime
+}
+
+// IsDir return file whether a directory
+func (fi bindataFileInfo) IsDir() bool {
+ return fi.mode&os.ModeDir != 0
+}
+
+// Sys return file is sys mode
+func (fi bindataFileInfo) Sys() interface{} {
+ return nil
+}
+
+var __001_initDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x72\x75\xf7\xf4\xb3\xe6\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\xf0\x74\x53\x70\x8d\xf0\x0c\x0e\x09\x56\x28\x2d\x4e\x2d\x8a\x2f\x4e\xce\x2f\x4a\xc5\xa1\x20\x31\xb9\x24\x33\x3f\xcf\x9a\xcb\xd9\xdf\xd7\xd7\x33\xc4\x9a\x0b\x10\x00\x00\xff\xff\x8c\xa0\x7b\x43\x4d\x00\x00\x00")
+
+func _001_initDownSqlBytes() ([]byte, error) {
+ return bindataRead(
+ __001_initDownSql,
+ "001_init.down.sql",
+ )
+}
+
+func _001_initDownSql() (*asset, error) {
+ bytes, err := _001_initDownSqlBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "001_init.down.sql", size: 77, mode: os.FileMode(420), modTime: time.Unix(1712472256, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var __001_initUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x92\x31\x6f\xc2\x30\x10\x85\xf7\xfc\x8a\xb7\x01\x2a\x0b\x33\x93\x13\x2e\xc8\xaa\xe3\xb4\xb6\xa3\x96\x29\x32\xc4\xad\xa2\x42\x40\xc1\x54\xe2\xdf\x57\xc1\x14\x1a\xd1\x4a\x15\xf3\x7d\xf7\xee\xdd\xbd\x8b\x69\xce\xe5\x34\x4a\x14\x31\x43\x30\x2c\x16\x84\xc3\xde\xb5\xe5\x7e\xb5\x6d\x1d\x86\x11\x00\xd4\x15\xb8\x34\x98\x93\x24\xc5\x0c\xcd\x10\x2f\x30\xa3\x94\x15\xc2\x80\x69\xf0\x19\x49\xc3\xcd\x62\x7c\x82\xbb\xee\xc6\x6e\x1c\x0c\xbd\x1a\x14\x92\x3f\x17\x04\x99\x1b\xc8\x42\x88\x80\x2c\x0f\x6d\x53\xfa\xba\x63\x78\x46\xda\xb0\xec\xe9\x42\x5c\x84\x65\xfe\x32\x1c\xe1\x01\x75\xe3\x5d\xfb\x69\xd7\x18\x4c\x50\xd9\xe3\x20\x48\x04\x7b\x3a\x63\x42\x74\xd6\xfa\xfa\xab\xd6\x59\xef\xaa\xd2\x7a\x74\x53\xf6\xde\x6e\x76\x7f\x0c\x88\x46\xd3\xa8\xbf\xbd\x5d\xf9\x7a\xdb\xdc\xb3\xf9\x75\xeb\xbe\x9d\x8d\x7d\x6f\x6a\x7f\xa8\xce\x7e\x35\x29\xce\xc4\xad\x9f\x49\xa0\x5b\xb7\x73\xd6\xdb\xe5\xda\x21\xce\x73\x41\x4c\xde\xa2\x29\x13\x9a\x02\xee\x8f\xbb\x5f\x87\x56\xdb\xe6\x7f\x02\xfd\xbc\xee\x3e\x64\x68\x08\x71\x0f\xbf\x35\xc7\xa7\x9b\x9c\x6b\x49\x2e\xb5\x51\xac\xbb\xe7\xdb\x47\x79\x7d\xb2\x53\x11\x48\x73\x45\x7c\x2e\xf1\x48\x8b\x4b\xff\x08\xe7\xa2\xa2\x94\x14\xc9\x84\xf4\x8f\xef\xbc\x62\x5d\x8a\x49\x9e\x65\xdc\x4c\xa3\xaf\x00\x00\x00\xff\xff\x2f\x40\x52\xc4\xd2\x02\x00\x00")
+
+func _001_initUpSqlBytes() ([]byte, error) {
+ return bindataRead(
+ __001_initUpSql,
+ "001_init.up.sql",
+ )
+}
+
+func _001_initUpSql() (*asset, error) {
+ bytes, err := _001_initUpSqlBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "001_init.up.sql", size: 722, mode: os.FileMode(420), modTime: time.Unix(1712472259, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+// Asset loads and returns the asset for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func Asset(name string) ([]byte, error) {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
+ a, err := f()
+ if err != nil {
+ return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+ }
+ return a.bytes, nil
+ }
+ return nil, fmt.Errorf("Asset %s not found", name)
+}
+
+// MustAsset is like Asset but panics when Asset would return an error.
+// It simplifies safe initialization of global variables.
+func MustAsset(name string) []byte {
+ a, err := Asset(name)
+ if err != nil {
+ panic("asset: Asset(" + name + "): " + err.Error())
+ }
+
+ return a
+}
+
+// AssetInfo loads and returns the asset info for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func AssetInfo(name string) (os.FileInfo, error) {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
+ a, err := f()
+ if err != nil {
+ return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
+ }
+ return a.info, nil
+ }
+ return nil, fmt.Errorf("AssetInfo %s not found", name)
+}
+
+// AssetNames returns the names of the assets.
+func AssetNames() []string {
+ names := make([]string, 0, len(_bindata))
+ for name := range _bindata {
+ names = append(names, name)
+ }
+ return names
+}
+
+// _bindata is a table, holding each asset generator, mapped to its name.
+var _bindata = map[string]func() (*asset, error){
+ "001_init.down.sql": _001_initDownSql,
+ "001_init.up.sql": _001_initUpSql,
+}
+
+// AssetDir returns the file names below a certain
+// directory embedded in the file by go-bindata.
+// For example if you run go-bindata on data/... and data contains the
+// following hierarchy:
+// data/
+// foo.txt
+// img/
+// a.png
+// b.png
+// then AssetDir("data") would return []string{"foo.txt", "img"}
+// AssetDir("data/img") would return []string{"a.png", "b.png"}
+// AssetDir("foo.txt") and AssetDir("notexist") would return an error
+// AssetDir("") will return []string{"data"}.
+func AssetDir(name string) ([]string, error) {
+ node := _bintree
+ if len(name) != 0 {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ pathList := strings.Split(cannonicalName, "/")
+ for _, p := range pathList {
+ node = node.Children[p]
+ if node == nil {
+ return nil, fmt.Errorf("Asset %s not found", name)
+ }
+ }
+ }
+ if node.Func != nil {
+ return nil, fmt.Errorf("Asset %s not found", name)
+ }
+ rv := make([]string, 0, len(node.Children))
+ for childName := range node.Children {
+ rv = append(rv, childName)
+ }
+ return rv, nil
+}
+
+type bintree struct {
+ Func func() (*asset, error)
+ Children map[string]*bintree
+}
+
+var _bintree = &bintree{nil, map[string]*bintree{
+ "001_init.down.sql": &bintree{_001_initDownSql, map[string]*bintree{}},
+ "001_init.up.sql": &bintree{_001_initUpSql, map[string]*bintree{}},
+}}
+
+// RestoreAsset restores an asset under the given directory
+func RestoreAsset(dir, name string) error {
+ data, err := Asset(name)
+ if err != nil {
+ return err
+ }
+ info, err := AssetInfo(name)
+ if err != nil {
+ return err
+ }
+ err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
+ if err != nil {
+ return err
+ }
+ err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// RestoreAssets restores an asset under the given directory recursively
+func RestoreAssets(dir, name string) error {
+ children, err := AssetDir(name)
+ // File
+ if err != nil {
+ return RestoreAsset(dir, name)
+ }
+ // Dir
+ for _, child := range children {
+ err = RestoreAssets(dir, filepath.Join(name, child))
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func _filePath(dir, name string) string {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+}
diff --git a/internal/database/repos/main.go b/internal/database/repos/main.go
new file mode 100644
index 0000000..e6f50be
--- /dev/null
+++ b/internal/database/repos/main.go
@@ -0,0 +1,15 @@
+package repos
+
+import (
+ "github.com/jmoiron/sqlx"
+)
+
+type Provider struct {
+ db *sqlx.DB
+}
+
+func NewProvider(conn *sqlx.DB) *Provider {
+ return &Provider{
+ db: conn,
+ }
+}
diff --git a/internal/database/sql/main.go b/internal/database/sql/main.go
new file mode 100644
index 0000000..80d5f5c
--- /dev/null
+++ b/internal/database/sql/main.go
@@ -0,0 +1,141 @@
+package database
+
+import (
+ "apjournal/internal/database/migrations"
+ "os"
+ "time"
+
+ "github.com/jmoiron/sqlx"
+
+ // driver postgres for migrations
+ "log/slog"
+
+ "github.com/golang-migrate/migrate"
+ _ "github.com/golang-migrate/migrate/database/postgres"
+ bindata "github.com/golang-migrate/migrate/source/go_bindata"
+ _ "github.com/jackc/pgx/v5/stdlib" // register pgx driver
+ "github.com/pkg/errors"
+)
+
+var log = slog.New(slog.NewJSONHandler(os.Stdout, nil))
+
+type DB struct {
+ Conn *sqlx.DB
+ URI string
+}
+
+func (d *DB) CloseAll() error {
+ for _, conn := range []*sqlx.DB{d.Conn} {
+ if err := closeConn(conn); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func closeConn(conn *sqlx.DB) error {
+ return conn.Close()
+}
+
+func Init(DBURI string) (*DB, error) {
+ var result DB
+ var err error
+ result.Conn, err = openDBConnection(DBURI, "pgx")
+ if err != nil {
+ return nil, err
+ }
+ result.URI = DBURI
+
+ if err := testConnection(result.Conn); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func InitWithMigrate(DBURI string, up bool) (*DB, error) {
+ var (
+ result DB
+ err error
+ )
+ result.Conn, err = openDBConnection(DBURI, "pgx")
+ if err != nil {
+ return nil, err
+ }
+ result.URI = DBURI
+
+ if err = testConnection(result.Conn); err != nil {
+ return nil, err
+ }
+ if err = result.Migrate(DBURI, up); err != nil {
+ return nil, err
+ }
+ return &result, nil
+}
+
+func openDBConnection(dbURI, driver string) (*sqlx.DB, error) {
+ conn, err := sqlx.Open(driver, dbURI)
+ if err != nil {
+ return nil, err
+ }
+ return conn, nil
+}
+
+func testConnection(conn *sqlx.DB) error {
+ err := conn.Ping()
+ if err != nil {
+ return errors.Wrap(err, "can't ping database")
+ }
+ return nil
+}
+
+func (db *DB) Migrate(url string, up bool) error {
+ source := bindata.Resource(migrations.AssetNames(), migrations.Asset)
+ driver, err := bindata.WithInstance(source)
+ if err != nil {
+ return errors.WithStack(errors.WithMessage(err,
+ "unable to instantiate driver from bindata"))
+ }
+ migration, err := migrate.NewWithSourceInstance("go-bindata",
+ driver, url)
+ if err != nil {
+ return errors.WithStack(errors.WithMessage(err,
+ "unable to start migration"))
+ }
+ if up {
+ if err = migration.Up(); err != nil && err.Error() != "no change" {
+ return errors.WithStack(errors.WithMessage(err,
+ "unable to migrate up"))
+ }
+ } else {
+ if err = migration.Down(); err != nil &&
+ err.Error() != "no change" {
+ return errors.WithStack(errors.WithMessage(err,
+ "unable to migrate down"))
+ }
+ }
+ return nil
+}
+
+func (d *DB) PingRoutine(interval time.Duration) {
+ ticker := time.NewTicker(interval)
+ done := make(chan bool)
+
+ for {
+ select {
+ case <-done:
+ return
+ case t := <-ticker.C:
+ if err := testConnection(d.Conn); err != nil {
+ log.Error("failed to ping postrges db", "error", err, "ping_at", t)
+ // reconnect
+ if err := closeConn(d.Conn); err != nil {
+ log.Error("failed to close db connection", "error", err, "ping_at", t)
+ }
+ d.Conn, err = openDBConnection(d.URI, "pgx")
+ if err != nil {
+ log.Error("failed to reconnect", "error", err, "ping_at", t)
+ }
+ }
+ }
+ }
+}
diff --git a/internal/handlers/main.go b/internal/handlers/main.go
index dc8ba2b..efafcde 100644
--- a/internal/handlers/main.go
+++ b/internal/handlers/main.go
@@ -2,33 +2,37 @@ package handlers
import (
"apjournal/config"
+ "apjournal/internal/database/repos"
"apjournal/internal/models"
"html/template"
"log/slog"
"net/http"
"os"
"strconv"
+ "time"
+
+ "github.com/jmoiron/sqlx"
)
// Handlers structure
type Handlers struct {
- cfg config.Config
- // s *service.Service
- log *slog.Logger
+ cfg config.Config
+ log *slog.Logger
+ repo *repos.Provider
}
// NewHandlers constructor
func NewHandlers(
// cfg config.Config, s *service.Service, l *slog.Logger,
- cfg config.Config, l *slog.Logger,
+ cfg config.Config, l *slog.Logger, conn *sqlx.DB,
) *Handlers {
if l == nil {
l = slog.New(slog.NewJSONHandler(os.Stdout, nil))
}
h := &Handlers{
- cfg: cfg,
- // s: s,
- log: l,
+ cfg: cfg,
+ log: l,
+ repo: repos.NewProvider(conn),
}
return h
}
@@ -49,7 +53,8 @@ func (h *Handlers) MainPage(w http.ResponseWriter, r *http.Request) {
panic(err)
}
// tmpl.Execute(w, us)
- us.ID = "test"
+ us.Username = "test"
+ us.BurnTime = time.Now().Add(time.Duration(24) * time.Hour)
tmpl.ExecuteTemplate(w, "main", us)
}
@@ -88,16 +93,18 @@ func (h *Handlers) HandleForm(w http.ResponseWriter, r *http.Request) {
Type: at,
Repeatable: repeat,
}
+ // TODO: check that name + userid key is unique
us.Actions = append(us.Actions, act)
tmpl := template.Must(template.ParseGlob("components/*.html"))
// tmpl := template.Must(template.ParseFiles("components/index.html"))
// tmpl.Execute(w, us)
+ // TODO: redirect to the main page instead
tmpl.ExecuteTemplate(w, "main", us)
}
func (h *Handlers) HandleDoneAction(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
- h.log.Info("got postform request", "payload", r.PostForm)
+ h.log.Info("got done request", "payload", r.PostForm)
actionName := r.PostFormValue("name")
h.log.Info("got postform request", "name", actionName)
// change counter of user score
diff --git a/internal/models/models.go b/internal/models/models.go
index 5d6dfa6..58191a2 100644
--- a/internal/models/models.go
+++ b/internal/models/models.go
@@ -11,16 +11,18 @@ const (
type (
UserScore struct {
- ID string
+ Username string
Actions []Action
BurnTime time.Time
Score int8
}
Action struct {
+ ID uint32
Name string
Magnitude uint8
Repeatable bool
Type ActionType
Done bool
+ Username string
}
)
diff --git a/internal/server/main.go b/internal/server/main.go
index 45f3d41..95d0369 100644
--- a/internal/server/main.go
+++ b/internal/server/main.go
@@ -9,6 +9,8 @@ import (
"os"
"os/signal"
"syscall"
+
+ "github.com/jmoiron/sqlx"
)
// Server interface
@@ -39,11 +41,9 @@ func (srv *server) stopOnSignal(close context.CancelFunc) {
os.Exit(0)
}
-func NewServer(cfg config.Config, log *slog.Logger) Server {
+func NewServer(cfg config.Config, log *slog.Logger, conn *sqlx.DB) Server {
ctx, close := context.WithCancel(context.Background())
- // s := service.NewService(ctx, cfg, store.MemCache)
- actions := handlers.NewHandlers(cfg, log)
-
+ actions := handlers.NewHandlers(cfg, log, conn)
return &server{
config: cfg,
actions: actions,
diff --git a/internal/service/main.go b/internal/service/main.go
deleted file mode 100644
index e69de29..0000000
--- a/internal/service/main.go
+++ /dev/null