Initial commot

Have got DB creation and migration working
This commit is contained in:
Leon Mika 2025-01-27 07:39:19 +11:00
commit 4ecc12f035
14 changed files with 315 additions and 0 deletions

9
docker-compose.yml Normal file
View file

@ -0,0 +1,9 @@
version: "3"
services:
db:
image: "postgres:17.2"
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: postgres

32
gen/sqlc/dbq/db.go Normal file
View file

@ -0,0 +1,32 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.28.0
package dbq
import (
"context"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
)
type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
return &Queries{
db: tx,
}
}

13
gen/sqlc/dbq/models.go Normal file
View file

@ -0,0 +1,13 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.28.0
package dbq
type Site struct {
ID int64
Name string
Url string
Theme string
Props []byte
}

56
gen/sqlc/dbq/sites.sql.go Normal file
View file

@ -0,0 +1,56 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.28.0
// source: sites.sql
package dbq
import (
"context"
)
const listSites = `-- name: ListSites :one
SELECT id, name, url, theme, props FROM site
`
func (q *Queries) ListSites(ctx context.Context) (Site, error) {
row := q.db.QueryRow(ctx, listSites)
var i Site
err := row.Scan(
&i.ID,
&i.Name,
&i.Url,
&i.Theme,
&i.Props,
)
return i, err
}
const newSite = `-- name: NewSite :one
INSERT INTO site (
name,
url,
theme,
props
) VALUES ($1, $2, $3, $4)
RETURNING id
`
type NewSiteParams struct {
Name string
Url string
Theme string
Props []byte
}
func (q *Queries) NewSite(ctx context.Context, arg NewSiteParams) (int64, error) {
row := q.db.QueryRow(ctx, newSite,
arg.Name,
arg.Url,
arg.Theme,
arg.Props,
)
var id int64
err := row.Scan(&id)
return id, err
}

21
go.mod Normal file
View file

@ -0,0 +1,21 @@
module lmika.dev/lmika/hugo-crm
go 1.23.3
require (
github.com/golang-migrate/migrate/v4 v4.18.1
github.com/jackc/pgx/v5 v5.7.2
)
require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
go.uber.org/atomic v1.7.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/text v0.21.0 // indirect
)

33
go.sum Normal file
View file

@ -0,0 +1,33 @@
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/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y=
github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6hFJUX53drDT4UsSW3DEhKn0ifuHw=
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds=
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-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
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=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

30
main.go Normal file
View file

@ -0,0 +1,30 @@
package main
import (
"context"
"lmika.dev/lmika/hugo-crm/models"
"lmika.dev/lmika/hugo-crm/providers/db"
"log"
)
func main() {
dbp, err := db.New("postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer dbp.Close()
log.Println("Connected to database")
if err := dbp.Migrate(context.Background()); err != nil {
log.Fatal(err)
}
log.Println("Database migrated")
if err := dbp.InsertSite(context.Background(), &models.Site{
Name: "Test site",
URL: "https://www.testsite.com",
}); err != nil {
log.Fatal(err)
}
}

7
models/sites.go Normal file
View file

@ -0,0 +1,7 @@
package models
type Site struct {
ID int64
Name string
URL string
}

59
providers/db/provider.go Normal file
View file

@ -0,0 +1,59 @@
package db
import (
"context"
"errors"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/pgx/v5"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/jackc/pgx/v5/pgxpool"
"lmika.dev/lmika/hugo-crm/gen/sqlc/dbq"
"lmika.dev/lmika/hugo-crm/sql"
"strings"
)
type DB struct {
url string
pool *pgxpool.Pool
q *dbq.Queries
}
func New(url string) (*DB, error) {
pool, err := pgxpool.New(context.Background(), url)
if err != nil {
return nil, err
}
return &DB{
url: url,
pool: pool,
q: dbq.New(pool),
}, nil
}
func (db *DB) Close() {
db.pool.Close()
}
func (db *DB) Ping(ctx context.Context) error {
return db.pool.Ping(ctx)
}
func (db *DB) Migrate(ctx context.Context) error {
ms, err := iofs.New(sql.FS, "schema")
if err != nil {
return err
}
dbURL := "pgx5://" + strings.TrimPrefix(db.url, "postgres://")
m, err := migrate.NewWithSourceInstance("iofs", ms, dbURL)
if err != nil {
return err
}
err = m.Up()
if err != nil && !errors.Is(err, migrate.ErrNoChange) {
return err
}
return nil
}

21
providers/db/sites.go Normal file
View file

@ -0,0 +1,21 @@
package db
import (
"context"
"lmika.dev/lmika/hugo-crm/gen/sqlc/dbq"
"lmika.dev/lmika/hugo-crm/models"
)
func (db *DB) InsertSite(ctx context.Context, site *models.Site) error {
id, err := db.q.NewSite(ctx, dbq.NewSiteParams{
Name: site.Name,
Url: site.URL,
Theme: "default",
Props: []byte("{}"),
})
if err != nil {
return err
}
site.ID = id
return nil
}

6
sql/fs.go Normal file
View file

@ -0,0 +1,6 @@
package sql
import "embed"
//go:embed schema/*.sql
var FS embed.FS

11
sql/queries/sites.sql Normal file
View file

@ -0,0 +1,11 @@
-- name: ListSites :one
SELECT * FROM site;
-- name: NewSite :one
INSERT INTO site (
name,
url,
theme,
props
) VALUES ($1, $2, $3, $4)
RETURNING id;

7
sql/schema/1_init.up.sql Normal file
View file

@ -0,0 +1,7 @@
CREATE TABLE site (
id BIGSERIAL NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
url TEXT NOT NULL,
theme TEXT NOT NULL,
props JSON NOT NULL
);

10
sqlc.yaml Normal file
View file

@ -0,0 +1,10 @@
version: "2"
sql:
- engine: "postgresql"
queries: "sql/queries"
schema: "sql/schema"
gen:
go:
package: "dbq"
out: "gen/sqlc/dbq"
sql_package: "pgx/v5"