Skip to content

Commit 7e17a4a

Browse files
authored
refactor: replace gorm with vanilla sql and sqlc (#541)
* refactor: replace gorm with vanilla sql and sqlc * chore: go mod tidy * refactor: rebase for main * tests: fix tests * fix: review comments
1 parent 2dc047d commit 7e17a4a

16 files changed

Lines changed: 416 additions & 177 deletions

go.mod

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ require (
1111
github.com/charmbracelet/huh v0.8.0
1212
github.com/docker/docker v28.5.2+incompatible
1313
github.com/gin-gonic/gin v1.11.0
14-
github.com/glebarez/sqlite v1.11.0
1514
github.com/go-ldap/ldap/v3 v3.4.12
1615
github.com/golang-migrate/migrate/v4 v4.19.1
1716
github.com/google/go-querystring v1.2.0
@@ -24,8 +23,8 @@ require (
2423
golang.org/x/crypto v0.46.0
2524
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
2625
golang.org/x/oauth2 v0.34.0
27-
gorm.io/gorm v1.31.1
2826
gotest.tools/v3 v3.5.2
27+
modernc.org/sqlite v1.38.2
2928
)
3029

3130
require (
@@ -61,7 +60,6 @@ require (
6160
github.com/felixge/httpsnoop v1.0.4 // indirect
6261
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
6362
github.com/gin-contrib/sse v1.1.0 // indirect
64-
github.com/glebarez/go-sqlite v1.21.2 // indirect
6563
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
6664
github.com/go-logr/logr v1.4.3 // indirect
6765
github.com/go-logr/stdr v1.2.2 // indirect
@@ -73,8 +71,6 @@ require (
7371
github.com/google/go-cmp v0.7.0 // indirect
7472
github.com/huandu/xstrings v1.5.0 // indirect
7573
github.com/imdario/mergo v0.3.11 // indirect
76-
github.com/jinzhu/inflection v1.0.0 // indirect
77-
github.com/jinzhu/now v1.1.5 // indirect
7874
github.com/json-iterator/go v1.1.12 // indirect
7975
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
8076
github.com/leodido/go-urn v1.4.0 // indirect
@@ -126,6 +122,5 @@ require (
126122
modernc.org/libc v1.66.3 // indirect
127123
modernc.org/mathutil v1.7.1 // indirect
128124
modernc.org/memory v1.11.0 // indirect
129-
modernc.org/sqlite v1.38.2 // indirect
130125
rsc.io/qr v0.2.0 // indirect
131126
)

go.sum

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,6 @@ github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w
101101
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
102102
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
103103
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
104-
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
105-
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
106-
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
107-
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
108104
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
109105
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
110106
github.com/go-ldap/ldap/v3 v3.4.12 h1:1b81mv7MagXZ7+1r7cLTWmyuTqVqdwbtJSjC0DAp9s4=
@@ -161,10 +157,6 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6
161157
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
162158
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
163159
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
164-
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
165-
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
166-
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
167-
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
168160
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
169161
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
170162
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
@@ -375,8 +367,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
375367
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
376368
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
377369
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
378-
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
379-
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
380370
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
381371
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
382372
modernc.org/cc/v4 v4.26.2 h1:991HMkLjJzYBIfha6ECZdjrIYz2/1ayr+FL8GN+CNzM=

internal/bootstrap/app_bootstrap.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ import (
1414

1515
"github.com/steveiliop56/tinyauth/internal/config"
1616
"github.com/steveiliop56/tinyauth/internal/controller"
17-
"github.com/steveiliop56/tinyauth/internal/model"
17+
"github.com/steveiliop56/tinyauth/internal/repository"
1818
"github.com/steveiliop56/tinyauth/internal/utils"
1919

2020
"github.com/rs/zerolog/log"
21-
"gorm.io/gorm"
2221
)
2322

2423
type BootstrapApp struct {
@@ -108,8 +107,18 @@ func (app *BootstrapApp) Setup() error {
108107
log.Trace().Str("csrfCookieName", app.context.csrfCookieName).Msg("CSRF cookie name")
109108
log.Trace().Str("redirectCookieName", app.context.redirectCookieName).Msg("Redirect cookie name")
110109

110+
// Database
111+
db, err := app.SetupDatabase(app.config.DatabasePath)
112+
113+
if err != nil {
114+
return fmt.Errorf("failed to setup database: %w", err)
115+
}
116+
117+
// Queries
118+
queries := repository.New(db)
119+
111120
// Services
112-
services, err := app.initServices()
121+
services, err := app.initServices(queries)
113122

114123
if err != nil {
115124
return fmt.Errorf("failed to initialize services: %w", err)
@@ -155,9 +164,9 @@ func (app *BootstrapApp) Setup() error {
155164
return fmt.Errorf("failed to setup routes: %w", err)
156165
}
157166

158-
// Start DB cleanup routine
167+
// Start db cleanup routine
159168
log.Debug().Msg("Starting database cleanup routine")
160-
go app.dbCleanup(services.databaseService.GetDatabase())
169+
go app.dbCleanup(queries)
161170

162171
// If analytics are not disabled, start heartbeat
163172
if !app.config.DisableAnalytics {
@@ -247,16 +256,16 @@ func (app *BootstrapApp) heartbeat() {
247256
}
248257
}
249258

250-
func (app *BootstrapApp) dbCleanup(db *gorm.DB) {
259+
func (app *BootstrapApp) dbCleanup(queries *repository.Queries) {
251260
ticker := time.NewTicker(time.Duration(30) * time.Minute)
252261
defer ticker.Stop()
253262
ctx := context.Background()
254263

255264
for ; true; <-ticker.C {
256265
log.Debug().Msg("Cleaning up old database sessions")
257-
_, err := gorm.G[model.Session](db).Where("expiry < ?", time.Now().Unix()).Delete(ctx)
266+
err := queries.DeleteExpiredSessions(ctx, time.Now().Unix())
258267
if err != nil {
259-
log.Error().Err(err).Msg("Failed to cleanup old sessions")
268+
log.Error().Err(err).Msg("Failed to clean up old database sessions")
260269
}
261270
}
262271
}

internal/bootstrap/db_bootstrap.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package bootstrap
2+
3+
import (
4+
"database/sql"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
9+
"github.com/steveiliop56/tinyauth/internal/assets"
10+
11+
"github.com/golang-migrate/migrate/v4"
12+
"github.com/golang-migrate/migrate/v4/database/sqlite3"
13+
"github.com/golang-migrate/migrate/v4/source/iofs"
14+
_ "modernc.org/sqlite"
15+
)
16+
17+
func (app *BootstrapApp) SetupDatabase(databasePath string) (*sql.DB, error) {
18+
dir := filepath.Dir(databasePath)
19+
20+
if err := os.MkdirAll(dir, 0750); err != nil {
21+
return nil, fmt.Errorf("failed to create database directory %s: %w", dir, err)
22+
}
23+
24+
db, err := sql.Open("sqlite", databasePath)
25+
26+
if err != nil {
27+
return nil, fmt.Errorf("failed to open database: %w", err)
28+
}
29+
30+
migrations, err := iofs.New(assets.Migrations, "migrations")
31+
32+
if err != nil {
33+
return nil, fmt.Errorf("failed to create migrations: %w", err)
34+
}
35+
36+
target, err := sqlite3.WithInstance(db, &sqlite3.Config{})
37+
38+
if err != nil {
39+
return nil, fmt.Errorf("failed to create sqlite3 instance: %w", err)
40+
}
41+
42+
migrator, err := migrate.NewWithInstance("iofs", migrations, "sqlite3", target)
43+
44+
if err != nil {
45+
return nil, fmt.Errorf("failed to create migrator: %w", err)
46+
}
47+
48+
if err := migrator.Up(); err != nil && err != migrate.ErrNoChange {
49+
return nil, fmt.Errorf("failed to migrate database: %w", err)
50+
}
51+
52+
return db, nil
53+
}

internal/bootstrap/service_bootstrap.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package bootstrap
22

33
import (
4+
"github.com/steveiliop56/tinyauth/internal/repository"
45
"github.com/steveiliop56/tinyauth/internal/service"
56

67
"github.com/rs/zerolog/log"
@@ -9,27 +10,14 @@ import (
910
type Services struct {
1011
accessControlService *service.AccessControlsService
1112
authService *service.AuthService
12-
databaseService *service.DatabaseService
1313
dockerService *service.DockerService
1414
ldapService *service.LdapService
1515
oauthBrokerService *service.OAuthBrokerService
1616
}
1717

18-
func (app *BootstrapApp) initServices() (Services, error) {
18+
func (app *BootstrapApp) initServices(queries *repository.Queries) (Services, error) {
1919
services := Services{}
2020

21-
databaseService := service.NewDatabaseService(service.DatabaseServiceConfig{
22-
DatabasePath: app.config.DatabasePath,
23-
})
24-
25-
err := databaseService.Init()
26-
27-
if err != nil {
28-
return Services{}, err
29-
}
30-
31-
services.databaseService = databaseService
32-
3321
ldapService := service.NewLdapService(service.LdapServiceConfig{
3422
Address: app.config.Ldap.Address,
3523
BindDN: app.config.Ldap.BindDN,
@@ -39,7 +27,7 @@ func (app *BootstrapApp) initServices() (Services, error) {
3927
SearchFilter: app.config.Ldap.SearchFilter,
4028
})
4129

42-
err = ldapService.Init()
30+
err := ldapService.Init()
4331

4432
if err == nil {
4533
services.ldapService = ldapService
@@ -76,7 +64,7 @@ func (app *BootstrapApp) initServices() (Services, error) {
7664
LoginTimeout: app.config.Auth.LoginTimeout,
7765
LoginMaxRetries: app.config.Auth.LoginMaxRetries,
7866
SessionCookieName: app.context.sessionCookieName,
79-
}, dockerService, ldapService, databaseService.GetDatabase())
67+
}, dockerService, ldapService, queries)
8068

8169
err = authService.Init()
8270

internal/controller/proxy_controller_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import (
44
"net/http/httptest"
55
"testing"
66

7+
"github.com/steveiliop56/tinyauth/internal/bootstrap"
78
"github.com/steveiliop56/tinyauth/internal/config"
89
"github.com/steveiliop56/tinyauth/internal/controller"
10+
"github.com/steveiliop56/tinyauth/internal/repository"
911
"github.com/steveiliop56/tinyauth/internal/service"
1012

1113
"github.com/gin-gonic/gin"
@@ -26,14 +28,16 @@ func setupProxyController(t *testing.T, middlewares *[]gin.HandlerFunc) (*gin.En
2628
group := router.Group("/api")
2729
recorder := httptest.NewRecorder()
2830

31+
// Mock app
32+
app := bootstrap.NewBootstrapApp(config.Config{})
33+
2934
// Database
30-
databaseService := service.NewDatabaseService(service.DatabaseServiceConfig{
31-
DatabasePath: "/tmp/tinyauth_test.db",
32-
})
35+
db, err := app.SetupDatabase(":memory:")
3336

34-
assert.NilError(t, databaseService.Init())
37+
assert.NilError(t, err)
3538

36-
database := databaseService.GetDatabase()
39+
// Queries
40+
queries := repository.New(db)
3741

3842
// Docker
3943
dockerService := service.NewDockerService()
@@ -60,7 +64,7 @@ func setupProxyController(t *testing.T, middlewares *[]gin.HandlerFunc) (*gin.En
6064
LoginTimeout: 300,
6165
LoginMaxRetries: 3,
6266
SessionCookieName: "tinyauth-session",
63-
}, dockerService, nil, database)
67+
}, dockerService, nil, queries)
6468

6569
// Controller
6670
ctrl := controller.NewProxyController(controller.ProxyControllerConfig{

internal/controller/user_controller_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import (
88
"testing"
99
"time"
1010

11+
"github.com/steveiliop56/tinyauth/internal/bootstrap"
1112
"github.com/steveiliop56/tinyauth/internal/config"
1213
"github.com/steveiliop56/tinyauth/internal/controller"
14+
"github.com/steveiliop56/tinyauth/internal/repository"
1315
"github.com/steveiliop56/tinyauth/internal/service"
1416

1517
"github.com/gin-gonic/gin"
@@ -34,14 +36,16 @@ func setupUserController(t *testing.T, middlewares *[]gin.HandlerFunc) (*gin.Eng
3436
group := router.Group("/api")
3537
recorder := httptest.NewRecorder()
3638

39+
// Mock app
40+
app := bootstrap.NewBootstrapApp(config.Config{})
41+
3742
// Database
38-
databaseService := service.NewDatabaseService(service.DatabaseServiceConfig{
39-
DatabasePath: "/tmp/tinyauth_test.db",
40-
})
43+
db, err := app.SetupDatabase(":memory:")
4144

42-
assert.NilError(t, databaseService.Init())
45+
assert.NilError(t, err)
4346

44-
database := databaseService.GetDatabase()
47+
// Queries
48+
queries := repository.New(db)
4549

4650
// Auth service
4751
authService := service.NewAuthService(service.AuthServiceConfig{
@@ -63,7 +67,7 @@ func setupUserController(t *testing.T, middlewares *[]gin.HandlerFunc) (*gin.Eng
6367
LoginTimeout: 300,
6468
LoginMaxRetries: 3,
6569
SessionCookieName: "tinyauth-session",
66-
}, nil, nil, database)
70+
}, nil, nil, queries)
6771

6872
// Controller
6973
ctrl := controller.NewUserController(controller.UserControllerConfig{

internal/model/session_model.go

Lines changed: 0 additions & 14 deletions
This file was deleted.

internal/repository/db.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/repository/models.go

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)