Skip to content

Commit 04b8e98

Browse files
committed
feat(db): add memory storage driver
removes the sqlite dependency for tests, also brings back the option for users to run zero persistence instances of tinyauth. adds new mapErr fn for sqlc wrapper gen to prevent sql errors from leaking out of the store implementation.
1 parent 0244f39 commit 04b8e98

14 files changed

Lines changed: 435 additions & 69 deletions

File tree

cmd/gen/sqlc-wrapper/main.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,18 +449,18 @@ func buildBody(m methodInfo) string {
449449

450450
// no repo-typed result → direct return
451451
if len(m.Results) == 0 || m.Results[0].RepoType == "" {
452-
return "\treturn " + call + "\n"
452+
return "\treturn mapErr(" + call + ")\n"
453453
}
454454

455455
r := m.Results[0]
456456
if r.IsSlice {
457457
return fmt.Sprintf(
458-
"\trows, err := %s\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tout := make([]%s, len(rows))\n\tfor i, row := range rows {\n\t\tout[i] = %s(row)\n\t}\n\treturn out, nil\n",
458+
"\trows, err := %s\n\tif err != nil {\n\t\treturn nil, mapErr(err)\n\t}\n\tout := make([]%s, len(rows))\n\tfor i, row := range rows {\n\t\tout[i] = %s(row)\n\t}\n\treturn out, nil\n",
459459
call, r.RepoType, converterFn(r.TypeStr),
460460
)
461461
}
462462
return fmt.Sprintf(
463-
"\tr, err := %s\n\tif err != nil {\n\t\treturn %s{}, err\n\t}\n\treturn %s(r), nil\n",
463+
"\tr, err := %s\n\tif err != nil {\n\t\treturn %s{}, mapErr(err)\n\t}\n\treturn %s(r), nil\n",
464464
call, r.RepoType, converterFn(r.TypeStr),
465465
)
466466
}
@@ -477,6 +477,8 @@ package {{.PkgName}}
477477
478478
import (
479479
"context"
480+
"database/sql"
481+
"errors"
480482
481483
"{{.RepoPkg}}"
482484
)
@@ -491,6 +493,22 @@ func NewStore(q *Queries) repository.Store {
491493
return &Store{q: q}
492494
}
493495
496+
var errMap = []struct {
497+
from error
498+
to error
499+
}{
500+
{sql.ErrNoRows, repository.ErrNotFound},
501+
}
502+
503+
func mapErr(err error) error {
504+
for _, e := range errMap {
505+
if errors.Is(err, e.from) {
506+
return e.to
507+
}
508+
}
509+
return err
510+
}
511+
494512
{{range .ModelTypes -}}
495513
func {{converterFn .}}(v {{.}}) repository.{{.}} {
496514
return repository.{{.}}(v)

internal/bootstrap/db_bootstrap.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/tinyauthapp/tinyauth/internal/assets"
1010
"github.com/tinyauthapp/tinyauth/internal/repository"
11+
"github.com/tinyauthapp/tinyauth/internal/repository/memory"
1112
"github.com/tinyauthapp/tinyauth/internal/repository/sqlite"
1213

1314
"github.com/golang-migrate/migrate/v4"
@@ -17,14 +18,14 @@ import (
1718
)
1819

1920
func (app *BootstrapApp) SetupStore() (repository.Store, error) {
20-
return app.setupSQLite(app.config.Database.Path)
21-
}
22-
23-
// NewSQLiteStore opens a SQLite database at the given path, runs migrations, and returns a Store.
24-
// Useful for testing or when constructing a store outside of a BootstrapApp.
25-
func NewSQLiteStore(databasePath string) (repository.Store, error) {
26-
app := &BootstrapApp{}
27-
return app.setupSQLite(databasePath)
21+
switch app.config.Database.Driver {
22+
case "memory":
23+
return memory.New(), nil
24+
case "sqlite", "":
25+
return app.setupSQLite(app.config.Database.Path)
26+
default:
27+
return nil, fmt.Errorf("unknown database driver %q: valid values are sqlite, memory", app.config.Database.Driver)
28+
}
2829
}
2930

3031
func (app *BootstrapApp) setupSQLite(databasePath string) (repository.Store, error) {

internal/config/config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ package config
44
func NewDefaultConfiguration() *Config {
55
return &Config{
66
Database: DatabaseConfig{
7-
Path: "./tinyauth.db",
7+
Driver: "sqlite",
8+
Path: "./tinyauth.db",
89
},
910
Analytics: AnalyticsConfig{
1011
Enabled: true,
@@ -95,7 +96,8 @@ type Config struct {
9596
}
9697

9798
type DatabaseConfig struct {
98-
Path string `description:"The path to the SQLite database, including file name." yaml:"path"`
99+
Driver string `description:"The database driver to use. Valid values: sqlite, memory." yaml:"driver"`
100+
Path string `description:"The path to the SQLite database, including file name. Only used when driver is sqlite." yaml:"path"`
99101
}
100102

101103
type AnalyticsConfig struct {

internal/controller/oidc_controller_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import (
1212

1313
"github.com/gin-gonic/gin"
1414
"github.com/google/go-querystring/query"
15-
"github.com/tinyauthapp/tinyauth/internal/bootstrap"
1615
"github.com/tinyauthapp/tinyauth/internal/config"
1716
"github.com/tinyauthapp/tinyauth/internal/controller"
17+
"github.com/tinyauthapp/tinyauth/internal/repository/memory"
1818
"github.com/tinyauthapp/tinyauth/internal/service"
1919
"github.com/tinyauthapp/tinyauth/internal/utils/tlog"
2020
"github.com/stretchr/testify/assert"
@@ -847,11 +847,10 @@ func TestOIDCController(t *testing.T) {
847847
},
848848
}
849849

850-
store, err := bootstrap.NewSQLiteStore(path.Join(tempDir, "tinyauth.db"))
851-
require.NoError(t, err)
850+
store := memory.New()
852851

853852
oidcService := service.NewOIDCService(oidcServiceCfg, store)
854-
err = oidcService.Init()
853+
err := oidcService.Init()
855854
require.NoError(t, err)
856855

857856
for _, test := range tests {

internal/controller/proxy_controller_test.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ package controller_test
22

33
import (
44
"net/http/httptest"
5-
"path"
65
"testing"
76

87
"github.com/gin-gonic/gin"
9-
"github.com/tinyauthapp/tinyauth/internal/bootstrap"
108
"github.com/tinyauthapp/tinyauth/internal/config"
119
"github.com/tinyauthapp/tinyauth/internal/controller"
10+
"github.com/tinyauthapp/tinyauth/internal/repository/memory"
1211
"github.com/tinyauthapp/tinyauth/internal/service"
1312
"github.com/tinyauthapp/tinyauth/internal/utils/tlog"
1413
"github.com/stretchr/testify/assert"
@@ -17,7 +16,6 @@ import (
1716

1817
func TestProxyController(t *testing.T) {
1918
tlog.NewTestLogger().Init()
20-
tempDir := t.TempDir()
2119

2220
authServiceCfg := service.AuthServiceConfig{
2321
Users: []config.User{
@@ -392,11 +390,10 @@ func TestProxyController(t *testing.T) {
392390

393391
oauthBrokerCfgs := make(map[string]config.OAuthServiceConfig)
394392

395-
store, err := bootstrap.NewSQLiteStore(path.Join(tempDir, "tinyauth.db"))
396-
require.NoError(t, err)
393+
store := memory.New()
397394

398395
docker := service.NewDockerService()
399-
err = docker.Init()
396+
err := docker.Init()
400397
require.NoError(t, err)
401398

402399
ldap := service.NewLdapService(service.LdapServiceConfig{})

internal/controller/user_controller_test.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ package controller_test
33
import (
44
"encoding/json"
55
"net/http/httptest"
6-
"path"
76
"strings"
87
"testing"
98
"time"
109

1110
"github.com/gin-gonic/gin"
1211
"github.com/pquerna/otp/totp"
13-
"github.com/tinyauthapp/tinyauth/internal/bootstrap"
1412
"github.com/tinyauthapp/tinyauth/internal/config"
1513
"github.com/tinyauthapp/tinyauth/internal/controller"
14+
"github.com/tinyauthapp/tinyauth/internal/repository/memory"
1615
"github.com/tinyauthapp/tinyauth/internal/service"
1716
"github.com/tinyauthapp/tinyauth/internal/utils/tlog"
1817
"github.com/stretchr/testify/assert"
@@ -21,7 +20,6 @@ import (
2120

2221
func TestUserController(t *testing.T) {
2322
tlog.NewTestLogger().Init()
24-
tempDir := t.TempDir()
2523

2624
authServiceCfg := service.AuthServiceConfig{
2725
Users: []config.User{
@@ -350,11 +348,10 @@ func TestUserController(t *testing.T) {
350348

351349
oauthBrokerCfgs := make(map[string]config.OAuthServiceConfig)
352350

353-
store, err := bootstrap.NewSQLiteStore(path.Join(tempDir, "tinyauth.db"))
354-
require.NoError(t, err)
351+
store := memory.New()
355352

356353
docker := service.NewDockerService()
357-
err = docker.Init()
354+
err := docker.Init()
358355
require.NoError(t, err)
359356

360357
ldap := service.NewLdapService(service.LdapServiceConfig{})

internal/controller/well_known_controller_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
"testing"
99

1010
"github.com/gin-gonic/gin"
11-
"github.com/tinyauthapp/tinyauth/internal/bootstrap"
1211
"github.com/tinyauthapp/tinyauth/internal/config"
1312
"github.com/tinyauthapp/tinyauth/internal/controller"
13+
"github.com/tinyauthapp/tinyauth/internal/repository/memory"
1414
"github.com/tinyauthapp/tinyauth/internal/service"
1515
"github.com/tinyauthapp/tinyauth/internal/utils/tlog"
1616
"github.com/stretchr/testify/assert"
@@ -100,11 +100,10 @@ func TestWellKnownController(t *testing.T) {
100100
},
101101
}
102102

103-
store, err := bootstrap.NewSQLiteStore(path.Join(tempDir, "tinyauth.db"))
104-
require.NoError(t, err)
103+
store := memory.New()
105104

106105
oidcService := service.NewOIDCService(oidcServiceCfg, store)
107-
err = oidcService.Init()
106+
err := oidcService.Init()
108107
require.NoError(t, err)
109108

110109
for _, test := range tests {

0 commit comments

Comments
 (0)