From bfa2ad6fd2258500ce2a29754501cff40e2d2ae4 Mon Sep 17 00:00:00 2001 From: Randell Date: Sun, 7 Apr 2024 14:45:57 -0600 Subject: [PATCH] Update for additional QoL and using golang migrate --- .gitignore | 1 + db/db.go | 54 +++++--- db/local.go | 42 +++++++ db/migrations/20240407203525_init.down.sql | 0 .../20240407203525_init.up.sql} | 0 db/models.go | 17 --- db/{ => queries}/query.sql | 0 db/query.sql.go | 115 ------------------ db/schema.go | 16 --- db/sqlite.go | 12 -- go.mod | 36 +++--- go.sum | 105 ++++++++++------ main.go | 14 +-- server/handler/handler.go | 8 +- server/middleware/logging.go | 2 +- server/router/router.go | 6 +- sqlc.yml | 9 +- 17 files changed, 186 insertions(+), 251 deletions(-) create mode 100644 db/local.go create mode 100644 db/migrations/20240407203525_init.down.sql rename db/{schema.sql => migrations/20240407203525_init.up.sql} (100%) delete mode 100644 db/models.go rename db/{ => queries}/query.sql (100%) delete mode 100644 db/query.sql.go delete mode 100644 db/schema.go delete mode 100644 db/sqlite.go diff --git a/.gitignore b/.gitignore index d10d018..d996491 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ Icon Network Trash Folder Temporary Items .apdisk +/db/queries/*.go diff --git a/db/db.go b/db/db.go index bdb151c..395be7e 100644 --- a/db/db.go +++ b/db/db.go @@ -1,31 +1,49 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.25.0 - package db import ( - "context" "database/sql" + "embed" + "fmt" + "go-htmx-template/db/queries" + "log/slog" + + "github.com/golang-migrate/migrate/v4" + "github.com/golang-migrate/migrate/v4/database/sqlite3" + "github.com/golang-migrate/migrate/v4/source/iofs" ) -type DBTX interface { - ExecContext(context.Context, string, ...interface{}) (sql.Result, error) - PrepareContext(context.Context, string) (*sql.Stmt, error) - QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) - QueryRowContext(context.Context, string, ...interface{}) *sql.Row -} +//go:embed migrations/*.sql +var migrations embed.FS -func New(db DBTX) *Queries { - return &Queries{db: db} +type Database interface { + DB() *sql.DB + Queries() *queries.Queries + Logger() *slog.Logger + Close() error } -type Queries struct { - db DBTX +func New(logger *slog.Logger, url string) (Database, error) { + return newLocalDB(logger, url) } -func (q *Queries) WithTx(tx *sql.Tx) *Queries { - return &Queries{ - db: tx, +// Migrate runs the migrations on the database. Assumes the database is SQLite. +func Migrate(db Database) error { + driver, err := sqlite3.WithInstance(db.DB(), &sqlite3.Config{}) + if err != nil { + return fmt.Errorf("failed to create database driver: %w", err) + } + + iofsDriver, err := iofs.New(migrations, "migrations") + if err != nil { + return fmt.Errorf("failed to create iofs: %w", err) + } + defer iofsDriver.Close() + + m, err := migrate.NewWithInstance("iofs", iofsDriver, "sqlite3", driver) + if err != nil { + return fmt.Errorf("failed to create migration: %w", err) } + defer m.Close() + + return m.Up() } diff --git a/db/local.go b/db/local.go new file mode 100644 index 0000000..d7ede06 --- /dev/null +++ b/db/local.go @@ -0,0 +1,42 @@ +package db + +import ( + "database/sql" + "go-htmx-template/db/queries" + "log/slog" + + _ "github.com/tursodatabase/libsql-client-go/libsql" + _ "modernc.org/sqlite" +) + +type LocalDB struct { + logger *slog.Logger + db *sql.DB + queries *queries.Queries +} + +var _ Database = (*LocalDB)(nil) + +func (d *LocalDB) DB() *sql.DB { + return d.db +} + +func (d *LocalDB) Queries() *queries.Queries { + return d.queries +} + +func (d *LocalDB) Logger() *slog.Logger { + return d.logger +} + +func (d *LocalDB) Close() error { + return d.db.Close() +} + +func newLocalDB(logger *slog.Logger, path string) (*LocalDB, error) { + db, err := sql.Open("libsql", "file:"+path) + if err != nil { + return nil, err + } + return &LocalDB{logger: logger, db: db, queries: queries.New(db)}, nil +} diff --git a/db/migrations/20240407203525_init.down.sql b/db/migrations/20240407203525_init.down.sql new file mode 100644 index 0000000..e69de29 diff --git a/db/schema.sql b/db/migrations/20240407203525_init.up.sql similarity index 100% rename from db/schema.sql rename to db/migrations/20240407203525_init.up.sql diff --git a/db/models.go b/db/models.go deleted file mode 100644 index ee14d93..0000000 --- a/db/models.go +++ /dev/null @@ -1,17 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.25.0 - -package db - -import ( - "database/sql" - "time" -) - -type Author struct { - ID int64 - CreatedAt time.Time - Name string - Bio sql.NullString -} diff --git a/db/query.sql b/db/queries/query.sql similarity index 100% rename from db/query.sql rename to db/queries/query.sql diff --git a/db/query.sql.go b/db/query.sql.go deleted file mode 100644 index e7d352d..0000000 --- a/db/query.sql.go +++ /dev/null @@ -1,115 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.25.0 -// source: query.sql - -package db - -import ( - "context" - "database/sql" -) - -const createAuthor = `-- name: CreateAuthor :one -INSERT INTO authors ( - name, bio -) VALUES ( - ?, ? -) -RETURNING id, created_at, name, bio -` - -type CreateAuthorParams struct { - Name string - Bio sql.NullString -} - -func (q *Queries) CreateAuthor(ctx context.Context, arg CreateAuthorParams) (Author, error) { - row := q.db.QueryRowContext(ctx, createAuthor, arg.Name, arg.Bio) - var i Author - err := row.Scan( - &i.ID, - &i.CreatedAt, - &i.Name, - &i.Bio, - ) - return i, err -} - -const deleteAuthor = `-- name: DeleteAuthor :exec -DELETE FROM authors -WHERE id = ? -` - -func (q *Queries) DeleteAuthor(ctx context.Context, id int64) error { - _, err := q.db.ExecContext(ctx, deleteAuthor, id) - return err -} - -const getAuthor = `-- name: GetAuthor :one -SELECT id, created_at, name, bio FROM authors -WHERE id = ? LIMIT 1 -` - -func (q *Queries) GetAuthor(ctx context.Context, id int64) (Author, error) { - row := q.db.QueryRowContext(ctx, getAuthor, id) - var i Author - err := row.Scan( - &i.ID, - &i.CreatedAt, - &i.Name, - &i.Bio, - ) - return i, err -} - -const listAuthors = `-- name: ListAuthors :many -SELECT id, created_at, name, bio FROM authors -ORDER BY name -` - -func (q *Queries) ListAuthors(ctx context.Context) ([]Author, error) { - rows, err := q.db.QueryContext(ctx, listAuthors) - if err != nil { - return nil, err - } - defer rows.Close() - var items []Author - for rows.Next() { - var i Author - if err := rows.Scan( - &i.ID, - &i.CreatedAt, - &i.Name, - &i.Bio, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const updateAuthor = `-- name: UpdateAuthor :exec -UPDATE authors -SET name = ?, -bio = ? -WHERE id = ? -` - -type UpdateAuthorParams struct { - Name string - Bio sql.NullString - ID int64 -} - -func (q *Queries) UpdateAuthor(ctx context.Context, arg UpdateAuthorParams) error { - _, err := q.db.ExecContext(ctx, updateAuthor, arg.Name, arg.Bio, arg.ID) - return err -} diff --git a/db/schema.go b/db/schema.go deleted file mode 100644 index 14e0e1f..0000000 --- a/db/schema.go +++ /dev/null @@ -1,16 +0,0 @@ -package db - -import ( - "context" - "database/sql" - _ "embed" -) - -//go:embed schema.sql -var Schema string - -// InitSchema initializes the database schema. -func InitSchema(ctx context.Context, db *sql.DB) error { - _, err := db.ExecContext(ctx, Schema) - return err -} diff --git a/db/sqlite.go b/db/sqlite.go deleted file mode 100644 index 9d408f0..0000000 --- a/db/sqlite.go +++ /dev/null @@ -1,12 +0,0 @@ -package db - -import ( - "database/sql" - - _ "modernc.org/sqlite" -) - -// NewSQLite creates a new SQLite database. -func NewSQLite(dataSourceName string) (*sql.DB, error) { - return sql.Open("sqlite", dataSourceName) -} diff --git a/go.mod b/go.mod index fd59129..ba7705e 100644 --- a/go.mod +++ b/go.mod @@ -3,26 +3,32 @@ module go-htmx-template go 1.21.6 require ( - github.com/a-h/templ v0.2.543 - modernc.org/sqlite v1.28.0 + github.com/a-h/templ v0.2.648 + github.com/golang-migrate/migrate/v4 v4.17.0 + github.com/tursodatabase/libsql-client-go v0.0.0-20240401075953-8e79a99d828a + modernc.org/sqlite v1.29.5 ) require ( + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-sqlite3 v1.14.22 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/tools v0.1.12 // indirect - lukechampine.com/uint128 v1.2.0 // indirect - modernc.org/cc/v3 v3.40.0 // indirect - modernc.org/ccgo/v3 v3.16.13 // indirect - modernc.org/libc v1.29.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect + golang.org/x/sys v0.19.0 // indirect + modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect + modernc.org/libc v1.49.2 // indirect modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.7.2 // indirect - modernc.org/opt v0.1.3 // indirect - modernc.org/strutil v1.1.3 // indirect - modernc.org/token v1.0.1 // indirect + modernc.org/memory v1.8.0 // indirect + modernc.org/strutil v1.2.0 // indirect + modernc.org/token v1.1.0 // indirect + nhooyr.io/websocket v1.8.11 // indirect ) diff --git a/go.sum b/go.sum index 1cee5de..fb2b917 100644 --- a/go.sum +++ b/go.sum @@ -1,55 +1,84 @@ -github.com/a-h/templ v0.2.543 h1:8YyLvyUtf0/IE2nIwZ62Z/m2o2NqwhnMynzOL78Lzbk= -github.com/a-h/templ v0.2.543/go.mod h1:jP908DQCwI08IrnTalhzSEH9WJqG/Q94+EODQcJGFUA= +github.com/a-h/templ v0.2.648 h1:A1ggHGIE7AONOHrFaDTM8SrqgqHL6fWgWCijQ21Zy9I= +github.com/a-h/templ v0.2.648/go.mod h1:SA7mtYwVEajbIXFRh3vKdYm/4FYyLQAtPH1+KxzGPA8= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/golang-migrate/migrate/v4 v4.17.0 h1:rd40H3QXU0AA4IoLllFcEAEo9dYKRHYND2gB4p7xcaU= +github.com/golang-migrate/migrate/v4 v4.17.0/go.mod h1:+Cp2mtLP4/aXDTKb9wmXYitdrNx2HGs45rbWAo6OsKM= 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/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06 h1:JLvn7D+wXjH9g4Jsjo+VqmzTUpl/LX7vfr6VOfSWTdM= +github.com/libsql/sqlite-antlr4-parser v0.0.0-20240327125255-dbf53b6cbf06/go.mod h1:FUkZ5OHjlGPjnM2UyGJz9TypXQFgYqw6AFNO1UiROTM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= -github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +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/tursodatabase/libsql-client-go v0.0.0-20240401075953-8e79a99d828a h1:LMz5RmEKz1epPZgUO3MtA5/X9Peudqm4rUoteSjLkho= +github.com/tursodatabase/libsql-client-go v0.0.0-20240401075953-8e79a99d828a/go.mod h1:2Fu26tjM011BLeR5+jwTfs6DX/fNMEWV/3CBZvggrA4= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= -lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw= -modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= -modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= -modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= -modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= -modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v1.29.0 h1:tTFRFq69YKCF2QyGNuRUQxKBm1uZZLubf6Cjh/pVHXs= -modernc.org/libc v1.29.0/go.mod h1:DaG/4Q3LRRdqpiLyP0C2m1B8ZMGkQ+cCgOIjEtQlYhQ= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk= +modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA= +modernc.org/ccgo/v4 v4.16.0/go.mod h1:dkNyWIjFrVIZ68DTo36vHK+6/ShBn4ysU61So6PIqCI= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= +modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= +modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8= +modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.49.2 h1:Orwx0/7S7n5GCug2ANrqW0e7ZBu1mteep7xFkZCNydk= +modernc.org/libc v1.49.2/go.mod h1:yMZuGkn7pXbKfoT/M35gFJOAEdSKdxL0q64sF7KqCDo= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= -modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= -modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= -modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= -modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= -modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= -modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= -modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= -modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= +modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE= +modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= +nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/main.go b/main.go index b497ff0..7960f2c 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "context" "go-htmx-template/db" "go-htmx-template/log" "go-htmx-template/server" @@ -15,25 +14,22 @@ func main() { log.GetOutput(), ) - database, err := db.NewSQLite("./db.sqlite3") + database, err := db.New(logger, "./db.sqlite3") if err != nil { logger.Error("Failed to create database", "error", err) os.Exit(1) } defer database.Close() - err = db.InitSchema(context.Background(), database) - if err != nil { - logger.Error("Failed to initialize schema", "error", err) - os.Exit(1) + if err = db.Migrate(database); err != nil { + logger.Error("failed to migrate database", "error", err) + return } - queries := db.New(database) - svr := server.New( logger, ":8080", - server.WithRouter(router.New(logger, queries)), + server.WithRouter(router.New(logger, database)), ) svr.StartAndWait() diff --git a/server/handler/handler.go b/server/handler/handler.go index 26a8a25..d9cd4c1 100644 --- a/server/handler/handler.go +++ b/server/handler/handler.go @@ -10,13 +10,15 @@ import ( // Handler handles requests. type Handler struct { - Logger *slog.Logger - Queries *db.Queries + Logger *slog.Logger + Database db.Database } func (h *Handler) html(ctx context.Context, w http.ResponseWriter, status int, t templ.Component) { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(status) - _ = t.Render(context.Background(), w) + if err := t.Render(ctx, w); err != nil { + h.Logger.Error("Failed to render component", "error", err) + } } diff --git a/server/middleware/logging.go b/server/middleware/logging.go index 5fff575..88b29cc 100644 --- a/server/middleware/logging.go +++ b/server/middleware/logging.go @@ -24,7 +24,7 @@ func NewLoggingMiddleware(logger *slog.Logger, handler http.Handler) *LoggingMid func (l *LoggingMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { start := time.Now() l.handler.ServeHTTP(w, r) - l.logger.Info( + l.logger.Debug( "Request recieved", slog.String("method", r.Method), slog.String("path", r.URL.Path), diff --git a/server/router/router.go b/server/router/router.go index b4bac6c..7e5ce57 100644 --- a/server/router/router.go +++ b/server/router/router.go @@ -9,10 +9,10 @@ import ( "net/http" ) -func New(logger *slog.Logger, queries *db.Queries) http.Handler { +func New(logger *slog.Logger, database db.Database) http.Handler { h := &handler.Handler{ - Logger: logger, - Queries: queries, + Logger: logger, + Database: database, } mux := http.NewServeMux() diff --git a/sqlc.yml b/sqlc.yml index 8a2dde9..8faabbc 100644 --- a/sqlc.yml +++ b/sqlc.yml @@ -1,9 +1,10 @@ version: 2 sql: - engine: sqlite - queries: db/query.sql - schema: db/schema.sql + queries: + - db/queries/query.sql + schema: db/migrations gen: go: - package: db - out: db + package: queries + out: db/queries