Skip to content

Commit dce5c2c

Browse files
committed
feat(db): add postgresql support
1 parent 8849d7e commit dce5c2c

18 files changed

Lines changed: 1443 additions & 9 deletions

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ require (
103103
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
104104
github.com/huandu/xstrings v1.5.0 // indirect
105105
github.com/huin/goupnp v1.3.0 // indirect
106+
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa // indirect
107+
github.com/jackc/pgpassfile v1.0.0 // indirect
108+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
109+
github.com/jackc/pgx/v5 v5.9.2 // indirect
110+
github.com/jackc/puddle/v2 v2.2.2 // indirect
106111
github.com/jsimonetti/rtnetlink v1.4.0 // indirect
107112
github.com/json-iterator/go v1.1.12 // indirect
108113
github.com/klauspost/compress v1.18.2 // indirect

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,16 @@ github.com/illarion/gonotify/v3 v3.0.2 h1:O7S6vcopHexutmpObkeWsnzMJt/r1hONIEogeV
251251
github.com/illarion/gonotify/v3 v3.0.2/go.mod h1:HWGPdPe817GfvY3w7cx6zkbzNZfi3QjcBm/wgVvEL1U=
252252
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
253253
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
254+
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6hFJUX53drDT4UsSW3DEhKn0ifuHw=
255+
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds=
256+
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
257+
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
258+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
259+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
260+
github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw=
261+
github.com/jackc/pgx/v5 v5.9.2/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
262+
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
263+
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
254264
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
255265
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
256266
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
@@ -398,6 +408,7 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
398408
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
399409
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
400410
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
411+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
401412
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
402413
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
403414
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=

internal/assets/assets.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ var FrontendAssets embed.FS
1111

1212
// Migrations
1313
//
14-
//go:embed migrations/sqlite/*.sql
14+
//go:embed migrations/sqlite/*.sql migrations/postgres/*.sql
1515
var Migrations embed.FS
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
DROP TABLE IF EXISTS "oidc_tokens";
2+
DROP TABLE IF EXISTS "oidc_userinfo";
3+
DROP TABLE IF EXISTS "oidc_codes";
4+
DROP TABLE IF EXISTS "sessions";
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
CREATE TABLE "sessions" (
2+
"uuid" TEXT NOT NULL PRIMARY KEY,
3+
"username" TEXT NOT NULL,
4+
"email" TEXT NOT NULL,
5+
"name" TEXT NOT NULL,
6+
"provider" TEXT NOT NULL,
7+
"totp_pending" BOOLEAN NOT NULL,
8+
"oauth_groups" TEXT NOT NULL DEFAULT '',
9+
"expiry" BIGINT NOT NULL,
10+
"created_at" BIGINT NOT NULL,
11+
"oauth_name" TEXT NOT NULL DEFAULT '',
12+
"oauth_sub" TEXT NOT NULL DEFAULT ''
13+
);
14+
15+
CREATE TABLE "oidc_codes" (
16+
"sub" TEXT NOT NULL UNIQUE,
17+
"code_hash" TEXT NOT NULL PRIMARY KEY,
18+
"scope" TEXT NOT NULL,
19+
"redirect_uri" TEXT NOT NULL,
20+
"client_id" TEXT NOT NULL,
21+
"expires_at" BIGINT NOT NULL,
22+
"nonce" TEXT NOT NULL DEFAULT '',
23+
"code_challenge" TEXT NOT NULL DEFAULT ''
24+
);
25+
26+
CREATE TABLE "oidc_tokens" (
27+
"sub" TEXT NOT NULL UNIQUE,
28+
"access_token_hash" TEXT NOT NULL PRIMARY KEY,
29+
"refresh_token_hash" TEXT NOT NULL,
30+
"code_hash" TEXT NOT NULL,
31+
"scope" TEXT NOT NULL,
32+
"client_id" TEXT NOT NULL,
33+
"token_expires_at" BIGINT NOT NULL,
34+
"refresh_token_expires_at" BIGINT NOT NULL,
35+
"nonce" TEXT NOT NULL DEFAULT ''
36+
);
37+
38+
CREATE TABLE "oidc_userinfo" (
39+
"sub" TEXT NOT NULL PRIMARY KEY,
40+
"name" TEXT NOT NULL,
41+
"preferred_username" TEXT NOT NULL,
42+
"email" TEXT NOT NULL,
43+
"groups" TEXT NOT NULL,
44+
"updated_at" BIGINT NOT NULL,
45+
"given_name" TEXT NOT NULL,
46+
"family_name" TEXT NOT NULL,
47+
"middle_name" TEXT NOT NULL,
48+
"nickname" TEXT NOT NULL,
49+
"profile" TEXT NOT NULL,
50+
"picture" TEXT NOT NULL,
51+
"website" TEXT NOT NULL,
52+
"gender" TEXT NOT NULL,
53+
"birthdate" TEXT NOT NULL,
54+
"zoneinfo" TEXT NOT NULL,
55+
"locale" TEXT NOT NULL,
56+
"phone_number" TEXT NOT NULL,
57+
"address" TEXT NOT NULL
58+
);

internal/bootstrap/db_bootstrap.go

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ import (
66
"os"
77
"path/filepath"
88

9-
"github.com/tinyauthapp/tinyauth/internal/assets"
10-
"github.com/tinyauthapp/tinyauth/internal/repository"
11-
"github.com/tinyauthapp/tinyauth/internal/repository/memory"
12-
"github.com/tinyauthapp/tinyauth/internal/repository/sqlite"
13-
149
"github.com/golang-migrate/migrate/v4"
10+
pgxmigrate "github.com/golang-migrate/migrate/v4/database/pgx/v5"
1511
"github.com/golang-migrate/migrate/v4/database/sqlite3"
1612
"github.com/golang-migrate/migrate/v4/source/iofs"
13+
_ "github.com/jackc/pgx/v5/stdlib"
1714
_ "modernc.org/sqlite"
15+
16+
"github.com/tinyauthapp/tinyauth/internal/assets"
17+
"github.com/tinyauthapp/tinyauth/internal/repository"
18+
"github.com/tinyauthapp/tinyauth/internal/repository/memory"
19+
"github.com/tinyauthapp/tinyauth/internal/repository/postgres"
20+
"github.com/tinyauthapp/tinyauth/internal/repository/sqlite"
1821
)
1922

2023
func (app *BootstrapApp) SetupStore() (repository.Store, error) {
@@ -23,8 +26,10 @@ func (app *BootstrapApp) SetupStore() (repository.Store, error) {
2326
return memory.New(), nil
2427
case "sqlite", "":
2528
return app.setupSQLite(app.config.Database.Path)
29+
case "postgres":
30+
return app.setupPostgres(app.config.Database.Path)
2631
default:
27-
return nil, fmt.Errorf("unknown database driver %q: valid values are sqlite, memory", app.config.Database.Driver)
32+
return nil, fmt.Errorf("unknown database driver %q: valid values are sqlite, postgres, memory", app.config.Database.Driver)
2833
}
2934
}
3035

@@ -78,3 +83,44 @@ func (app *BootstrapApp) setupSQLite(databasePath string) (repository.Store, err
7883

7984
return sqlite.NewStore(sqlite.New(db)), nil
8085
}
86+
87+
func (app *BootstrapApp) setupPostgres(databaseURL string) (repository.Store, error) {
88+
db, err := sql.Open("pgx", databaseURL)
89+
90+
if err != nil {
91+
return nil, fmt.Errorf("failed to open database: %w", err)
92+
}
93+
94+
// Close the database if there is an error during migration
95+
defer func() {
96+
if err != nil {
97+
db.Close()
98+
}
99+
}()
100+
101+
migrations, err := iofs.New(assets.Migrations, "migrations/postgres")
102+
103+
if err != nil {
104+
return nil, fmt.Errorf("failed to create migrations: %w", err)
105+
}
106+
107+
target, err := pgxmigrate.WithInstance(db, &pgxmigrate.Config{})
108+
109+
if err != nil {
110+
return nil, fmt.Errorf("failed to create postgres instance: %w", err)
111+
}
112+
113+
migrator, err := migrate.NewWithInstance("iofs", migrations, "pgx", target)
114+
115+
if err != nil {
116+
return nil, fmt.Errorf("failed to create migrator: %w", err)
117+
}
118+
119+
if err := migrator.Up(); err != nil && err != migrate.ErrNoChange {
120+
return nil, fmt.Errorf("failed to migrate database: %w", err)
121+
}
122+
123+
app.db = db
124+
125+
return postgres.NewStore(postgres.New(db)), nil
126+
}

internal/model/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ type Config struct {
9191
}
9292

9393
type DatabaseConfig struct {
94-
Driver string `description:"The database driver to use. Valid values: sqlite, memory." yaml:"driver"`
95-
Path string `description:"The path to the SQLite database, including file name. Only used when driver is sqlite." yaml:"path"`
94+
Driver string `description:"The database driver to use. Valid values: sqlite, postgres, memory." yaml:"driver"`
95+
Path string `description:"The path to the SQLite database file, or connection URL when driver is postgres." yaml:"path"`
9696
}
9797

9898
type AnalyticsConfig struct {

internal/repository/postgres/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.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package postgres
2+
3+
//go:generate go run github.com/tinyauthapp/tinyauth/gen/sqlc-wrapper -pkg github.com/tinyauthapp/tinyauth/internal/repository/postgres

internal/repository/postgres/models.go

Lines changed: 64 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)