feat: sqlc, nix formatting

This commit is contained in:
2025-04-16 00:58:44 -04:00
parent 32f85fd0be
commit 967e2650ad
74 changed files with 1962 additions and 6811 deletions

View File

@ -9,12 +9,17 @@ import (
_ "github.com/spotdemo4/dbmate-sqlite-modernc/pkg/driver/sqlite" // Modernc sqlite
)
func Migrate(url *url.URL, dbFS *embed.FS) error {
func Migrate(dsn string, dbFS *embed.FS) error {
if dbFS == nil {
return nil
}
db := dbmate.New(url)
dburl, err := url.Parse(dsn)
if err != nil {
return err
}
db := dbmate.New(dburl)
db.Driver()
db.FS = dbFS

View File

@ -1,74 +0,0 @@
package database
import (
"database/sql"
"fmt"
"net/url"
"runtime"
_ "github.com/lib/pq" // Postgres
"github.com/stephenafamo/bob"
)
func NewPostgresConnection(url *url.URL) (*bob.DB, error) {
db, err := sql.Open("postgres", postgresConnectionString(url))
if err != nil {
return nil, err
}
bobdb := bob.NewDB(db)
return &bobdb, nil
}
func postgresConnectionString(u *url.URL) string {
hostname := u.Hostname()
port := u.Port()
query := u.Query()
// support socket parameter for consistency with mysql
if query.Get("socket") != "" {
query.Set("host", query.Get("socket"))
query.Del("socket")
}
// default hostname
if hostname == "" && query.Get("host") == "" {
switch runtime.GOOS {
case "linux":
query.Set("host", "/var/run/postgresql")
case "darwin", "freebsd", "dragonfly", "openbsd", "netbsd":
query.Set("host", "/tmp")
default:
hostname = "localhost"
}
}
// host param overrides url hostname
if query.Get("host") != "" {
hostname = ""
}
// always specify a port
if query.Get("port") != "" {
port = query.Get("port")
query.Del("port")
}
if port == "" {
switch u.Scheme {
case "redshift":
port = "5439"
default:
port = "5432"
}
}
// generate output URL
out, _ := url.Parse(u.String())
// force scheme back to postgres if there was another postgres-compatible scheme
out.Scheme = "postgres"
out.Host = fmt.Sprintf("%s:%s", hostname, port)
out.RawQuery = query.Encode()
return out.String()
}

View File

@ -2,65 +2,28 @@ package database
import (
"database/sql"
"net/url"
"regexp"
"errors"
"strings"
"github.com/stephenafamo/bob"
"github.com/spotdemo4/trevstack/server/internal/sqlc"
_ "modernc.org/sqlite" // Sqlite
)
func NewSQLiteConnection(url *url.URL) (*bob.DB, error) {
db, err := sql.Open("sqlite", sqliteConnectionString(url))
func New(dsn string) (*sqlc.Queries, *sql.DB, error) {
// Validate dsn
sp := strings.Split(dsn, ":")
if len(sp) != 2 {
return nil, nil, errors.New("invalid dsn")
}
// Open db
db, err := sql.Open("sqlite", sp[1])
if err != nil {
return nil, err
return nil, nil, err
}
// Create new bob db
bobdb := bob.NewDB(db)
// Create new sqlc connection
sqlc := sqlc.New(db)
return &bobdb, nil
}
// ConnectionString converts a URL into a valid connection string
func sqliteConnectionString(u *url.URL) string {
// duplicate URL and remove scheme
newURL := *u
newURL.Scheme = ""
if newURL.Opaque == "" && newURL.Path != "" {
// When the DSN is in the form "scheme:/absolute/path" or
// "scheme://absolute/path" or "scheme:///absolute/path", url.Parse
// will consider the file path as :
// - "absolute" as the hostname
// - "path" (and the rest until "?") as the URL path.
// Instead, when the DSN is in the form "scheme:", the (relative) file
// path is stored in the "Opaque" field.
// See: https://pkg.go.dev/net/url#URL
//
// While Opaque is not escaped, the URL Path is. So, if .Path contains
// the file path, we need to un-escape it, and rebuild the full path.
newURL.Opaque = "//" + newURL.Host + mustUnescapePath(newURL.Path)
newURL.Path = ""
}
// trim duplicate leading slashes
str := regexp.MustCompile("^//+").ReplaceAllString(newURL.String(), "/")
return str
}
// MustUnescapePath unescapes a URL path, and panics if it fails.
// It is used during in cases where we are parsing a generated path.
func mustUnescapePath(s string) string {
if s == "" {
panic("missing path")
}
path, err := url.PathUnescape(s)
if err != nil {
panic(err)
}
return path
return sqlc, db, nil
}