diff --git a/cmd/bluebell/main.go b/cmd/bluebell/main.go index 74ccdb6..8fa68cd 100644 --- a/cmd/bluebell/main.go +++ b/cmd/bluebell/main.go @@ -88,24 +88,28 @@ func main() { } }() - db, err := bluebell.InitDB(config.DB) + db, err := bluebell.InitDB(filepath.Join(wd, config.DB)) if err != nil { logger.Logger.Fatal("Failed to open database", "err", err) return } // Listen must be called before Ready - ln, err := upg.Listen("tcp", config.Listen) + lnHttp, err := upg.Listen("tcp", config.Listen.Http) + if err != nil { + logger.Logger.Fatal("Listen failed", "err", err) + } + + lnApi, err := upg.Listen("tcp", config.Listen.Api) if err != nil { logger.Logger.Fatal("Listen failed", "err", err) } uploadHandler := upload.New(sitesFs, db) - serveHandler := serve.New(sitesFs, db, config.Domain) + serveHandler := serve.New(sitesFs, db) router := httprouter.New() - router.POST("/u/:site", uploadHandler.Handle) - router.GET("/*filepath", serveHandler.Handle) + router.POST("/u/:site/:branch", uploadHandler.Handle) router.POST("/sites/:host", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) { }) @@ -113,7 +117,23 @@ func main() { }) - server := &http.Server{ + serverHttp := &http.Server{ + Handler: serveHandler, + ReadTimeout: 1 * time.Minute, + ReadHeaderTimeout: 1 * time.Minute, + WriteTimeout: 1 * time.Minute, + IdleTimeout: 1 * time.Minute, + MaxHeaderBytes: 4 * humanize.MiByte, + } + logger.Logger.Info("HTTP server listening on", "addr", config.Listen.Http) + go func() { + err := serverHttp.Serve(lnHttp) + if !errors.Is(err, http.ErrServerClosed) { + logger.Logger.Fatal("Serve failed", "err", err) + } + }() + + serverApi := &http.Server{ Handler: router, ReadTimeout: 1 * time.Minute, ReadHeaderTimeout: 1 * time.Minute, @@ -121,11 +141,11 @@ func main() { IdleTimeout: 1 * time.Minute, MaxHeaderBytes: 4 * humanize.MiByte, } - logger.Logger.Info("HTTP server listening on", "addr", config.Listen) + logger.Logger.Info("API server listening on", "addr", config.Listen.Api) go func() { - err := server.Serve(ln) + err := serverApi.Serve(lnApi) if !errors.Is(err, http.ErrServerClosed) { - logger.Logger.Fatal("Serve failed", "err", err) + logger.Logger.Fatal("API Serve failed", "err", err) } }() @@ -140,5 +160,5 @@ func main() { os.Exit(1) }) - server.Shutdown(context.Background()) + serverHttp.Shutdown(context.Background()) } diff --git a/conf/conf.go b/conf/conf.go index d3314e2..a4b4ddf 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -1,26 +1,11 @@ package conf type Conf struct { - Listen string `yaml:"listen"` - DB string `yaml:"db"` - Domain string `yaml:"domain"` + Listen ListenConf `yaml:"listen"` + DB string `yaml:"db"` } -func SlugFromDomain(domain string) string { - a := []byte(domain) - for i := range a { - switch { - case a[i] == '-': - // skip - case a[i] >= 'A' && a[i] <= 'Z': - a[i] += 32 - case a[i] >= 'a' && a[i] <= 'z': - // skip - case a[i] >= '0' && a[i] <= '9': - // skip - default: - a[i] = '-' - } - } - return string(a) +type ListenConf struct { + Http string `yaml:"http"` + Api string `yaml:"api"` } diff --git a/conf/conf_test.go b/conf/conf_test.go deleted file mode 100644 index 7e4a75e..0000000 --- a/conf/conf_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package conf - -import ( - _ "embed" - "github.com/mrmelon54/trie" - "github.com/spf13/afero" - "github.com/stretchr/testify/assert" - "sync" - "testing" -) - -//go:embed test-sites.yml -var testSitesYml []byte - -func TestConfig_Load(t *testing.T) { - f := afero.NewMemMapFs() - create, err := f.Create("sites.yml") - assert.NoError(t, err) - _, err = create.Write(testSitesYml) - assert.NoError(t, err) - assert.NoError(t, create.Close()) - - c := New(f) - assert.NoError(t, c.Load()) - val, ok := c.m.GetByString("example-com") - assert.True(t, ok) - assert.Equal(t, SiteConf{Domain: "example.com", Token: "abcd1234"}, *val) -} - -func TestConfig_loadSlice(t *testing.T) { - c := &Conf{l: new(sync.RWMutex)} - c.loadSlice([]SiteConf{ - {Domain: "example.com", Token: "abcd1234"}, - }) - a, ok := c.m.GetByString("example-com") - assert.True(t, ok) - assert.Equal(t, SiteConf{Domain: "example.com", Token: "abcd1234"}, *a) -} - -func TestConfig_slugFromDomain(t *testing.T) { - c := &Conf{} - assert.Equal(t, "---------------", c.slugFromDomain("!\"#$%&'()*+,-./")) - assert.Equal(t, "0123456789", c.slugFromDomain("0123456789")) - assert.Equal(t, "-------", c.slugFromDomain(":;<=>?@")) - assert.Equal(t, "abcdefghijklmnopqrstuvwxyz", c.slugFromDomain("ABCDEFGHIJKLMNOPQRSTUVWXYZ")) - assert.Equal(t, "------", c.slugFromDomain("[\\]^_`")) - assert.Equal(t, "abcdefghijklmnopqrstuvwxyz", c.slugFromDomain("abcdefghijklmnopqrstuvwxyz")) - assert.Equal(t, "----", c.slugFromDomain("{|}~")) -} - -func FuzzConfig_slugFromDomain(f *testing.F) { - c := &Conf{} - f.Fuzz(func(t *testing.T, a string) { - b := c.slugFromDomain(a) - if len(a) != len(b) { - t.Fatalf("value '%s' (%d) did not match lengths with the output '%s' (%d)", a, len(a), b, len(b)) - } - }) -} - -func TestConfig_Get(t *testing.T) { - c := &Conf{l: new(sync.RWMutex), m: &trie.Trie[SiteConf]{}} - c.loadSlice([]SiteConf{ - {Domain: "example.com", Token: "abcd1234"}, - }) - val, n, ok := c.Get("example.com") - assert.True(t, ok) - assert.Equal(t, 11, n) - assert.Equal(t, SiteConf{Domain: "example.com", Token: "abcd1234"}, *val) -} diff --git a/conf/test-sites.yml b/conf/test-sites.yml deleted file mode 100644 index 496b918..0000000 --- a/conf/test-sites.yml +++ /dev/null @@ -1,2 +0,0 @@ -- domain: example.com - token: abcd1234 diff --git a/database/migrations/20240810115057_init.up.sql b/database/migrations/20240810115057_init.up.sql index 990fd13..1ae8865 100644 --- a/database/migrations/20240810115057_init.up.sql +++ b/database/migrations/20240810115057_init.up.sql @@ -1,8 +1,15 @@ CREATE TABLE sites ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - slug TEXT(8) NOT NULL, + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, domain TEXT NOT NULL, - token TEXT NOT NULL, - enable BOOL NOT NULL + token TEXT NOT NULL +); + +CREATE TABLE branches +( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + domain TEXT NOT NULL, + branch TEXT NOT NULL, + last_update DATETIME NOT NULL, + enable BOOLEAN NOT NULL ); diff --git a/database/models.go b/database/models.go index 06cc095..d042aa2 100644 --- a/database/models.go +++ b/database/models.go @@ -4,12 +4,20 @@ package database -import () +import ( + "time" +) + +type Branch struct { + ID int64 `json:"id"` + Domain string `json:"domain"` + Branch string `json:"branch"` + LastUpdate time.Time `json:"last_update"` + Enable bool `json:"enable"` +} type Site struct { - ID int32 `json:"id"` - Slug string `json:"slug"` + ID int64 `json:"id"` Domain string `json:"domain"` Token string `json:"token"` - Enable bool `json:"enable"` } diff --git a/database/queries/sites.sql b/database/queries/sites.sql index 9e06154..edd85f5 100644 --- a/database/queries/sites.sql +++ b/database/queries/sites.sql @@ -1,20 +1,23 @@ --- name: GetSiteBySlug :one -SELECT * -FROM sites -WHERE slug = ? -LIMIT 1; - -- name: GetSiteByDomain :one SELECT * FROM sites WHERE domain = ? LIMIT 1; --- name: EnableDomain :exec -INSERT INTO sites (slug, domain, token) -VALUES (?, ?, ?); +-- name: GetLastUpdatedByDomainBranch :one +SELECT last_update +FROM branches +WHERE domain = ? + AND branch = ? + AND enable = true +LIMIT 1; --- name: DeleteDomain :exec -UPDATE sites -SET enable = false -WHERE domain = ?; +-- name: AddSiteDomain :exec +INSERT INTO sites (domain, token) +VALUES (?, ?); + +-- name: SetDomainBranchEnabled :exec +UPDATE branches +SET enable = ? +WHERE domain = ? + AND branch = ?; diff --git a/database/sites.sql.go b/database/sites.sql.go index 1fc97aa..961027e 100644 --- a/database/sites.sql.go +++ b/database/sites.sql.go @@ -7,37 +7,47 @@ package database import ( "context" + "time" ) -const deleteDomain = `-- name: DeleteDomain :exec -UPDATE sites -SET enable = false -WHERE domain = ? +const addSiteDomain = `-- name: AddSiteDomain :exec +INSERT INTO sites (domain, token) +VALUES (?, ?) ` -func (q *Queries) DeleteDomain(ctx context.Context, domain string) error { - _, err := q.db.ExecContext(ctx, deleteDomain, domain) - return err -} - -const enableDomain = `-- name: EnableDomain :exec -INSERT INTO sites (slug, domain, token) -VALUES (?, ?, ?) -` - -type EnableDomainParams struct { - Slug string `json:"slug"` +type AddSiteDomainParams struct { Domain string `json:"domain"` Token string `json:"token"` } -func (q *Queries) EnableDomain(ctx context.Context, arg EnableDomainParams) error { - _, err := q.db.ExecContext(ctx, enableDomain, arg.Slug, arg.Domain, arg.Token) +func (q *Queries) AddSiteDomain(ctx context.Context, arg AddSiteDomainParams) error { + _, err := q.db.ExecContext(ctx, addSiteDomain, arg.Domain, arg.Token) return err } +const getLastUpdatedByDomainBranch = `-- name: GetLastUpdatedByDomainBranch :one +SELECT last_update +FROM branches +WHERE domain = ? + AND branch = ? + AND enable = true +LIMIT 1 +` + +type GetLastUpdatedByDomainBranchParams struct { + Domain string `json:"domain"` + Branch string `json:"branch"` +} + +func (q *Queries) GetLastUpdatedByDomainBranch(ctx context.Context, arg GetLastUpdatedByDomainBranchParams) (time.Time, error) { + row := q.db.QueryRowContext(ctx, getLastUpdatedByDomainBranch, arg.Domain, arg.Branch) + var last_update time.Time + err := row.Scan(&last_update) + return last_update, err +} + const getSiteByDomain = `-- name: GetSiteByDomain :one -SELECT id, slug, domain, token, enable +SELECT id, domain, token FROM sites WHERE domain = ? LIMIT 1 @@ -46,32 +56,24 @@ LIMIT 1 func (q *Queries) GetSiteByDomain(ctx context.Context, domain string) (Site, error) { row := q.db.QueryRowContext(ctx, getSiteByDomain, domain) var i Site - err := row.Scan( - &i.ID, - &i.Slug, - &i.Domain, - &i.Token, - &i.Enable, - ) + err := row.Scan(&i.ID, &i.Domain, &i.Token) return i, err } -const getSiteBySlug = `-- name: GetSiteBySlug :one -SELECT id, slug, domain, token, enable -FROM sites -WHERE slug = ? -LIMIT 1 +const setDomainBranchEnabled = `-- name: SetDomainBranchEnabled :exec +UPDATE branches +SET enable = ? +WHERE domain = ? + AND branch = ? ` -func (q *Queries) GetSiteBySlug(ctx context.Context, slug string) (Site, error) { - row := q.db.QueryRowContext(ctx, getSiteBySlug, slug) - var i Site - err := row.Scan( - &i.ID, - &i.Slug, - &i.Domain, - &i.Token, - &i.Enable, - ) - return i, err +type SetDomainBranchEnabledParams struct { + Enable bool `json:"enable"` + Domain string `json:"domain"` + Branch string `json:"branch"` +} + +func (q *Queries) SetDomainBranchEnabled(ctx context.Context, arg SetDomainBranchEnabledParams) error { + _, err := q.db.ExecContext(ctx, setDomainBranchEnabled, arg.Enable, arg.Domain, arg.Branch) + return err } diff --git a/go.mod b/go.mod index d6a858e..6d9299e 100644 --- a/go.mod +++ b/go.mod @@ -8,30 +8,28 @@ require ( github.com/dustin/go-humanize v1.0.1 github.com/golang-migrate/migrate/v4 v4.18.1 github.com/julienschmidt/httprouter v1.3.0 - github.com/mrmelon54/trie v0.0.3 github.com/spf13/afero v1.11.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - filippo.io/edwards25519 v1.1.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/charmbracelet/lipgloss v1.0.0 // indirect github.com/charmbracelet/x/ansi v0.6.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-sqlite3 v1.14.24 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 // indirect + golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect ) diff --git a/go.sum b/go.sum index ae0843a..8127b46 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,3 @@ -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= @@ -16,30 +10,10 @@ github.com/cloudflare/tableflip v1.2.3 h1:8I+B99QnnEWPHOY3fWipwVKxS70LGgUsslG7CS github.com/cloudflare/tableflip v1.2.3/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB37pUFMmv7j2E= 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/dhui/dktest v0.4.3 h1:wquqUxAFdcUgabAVLvSCOKOlag5cIZuaOjYIBOWdsR0= -github.com/dhui/dktest v0.4.3/go.mod h1:zNK8IwktWzQRm6I/l2Wjp7MakiyaFWv4G1hjmodmMTs= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4= -github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= 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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 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= @@ -57,22 +31,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mrmelon54/trie v0.0.3 h1:wZmws84FiGNBZJ00garLyQ2EQhtx0SipVoV7fK8+kZE= -github.com/mrmelon54/trie v0.0.3/go.mod h1:d3hl0YUBSWR3XN4S9BDLkGVzLT4VgwP2mZkBJM6uFpw= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -80,24 +42,16 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= -go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= -go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= -go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= -go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= -go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= -go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= -golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 h1:9kj3STMvgqy3YA4VQXBrN7925ICMxD5wzMRcgA30588= +golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/identifier.sqlite b/identifier.sqlite new file mode 100644 index 0000000..de9dac1 Binary files /dev/null and b/identifier.sqlite differ diff --git a/initdb.go b/initdb.go index 0d7d96e..b80f6d0 100644 --- a/initdb.go +++ b/initdb.go @@ -6,7 +6,7 @@ import ( "errors" "github.com/1f349/bluebell/database" "github.com/golang-migrate/migrate/v4" - "github.com/golang-migrate/migrate/v4/database/mysql" + "github.com/golang-migrate/migrate/v4/database/sqlite3" "github.com/golang-migrate/migrate/v4/source/iofs" ) @@ -18,15 +18,15 @@ func InitDB(p string) (*database.Queries, error) { if err != nil { return nil, err } - dbOpen, err := sql.Open("mysql", p) + dbOpen, err := sql.Open("sqlite3", p) if err != nil { return nil, err } - dbDrv, err := mysql.WithInstance(dbOpen, &mysql.Config{}) + dbDrv, err := sqlite3.WithInstance(dbOpen, &sqlite3.Config{}) if err != nil { return nil, err } - mig, err := migrate.NewWithInstance("iofs", migDrv, "mysql", dbDrv) + mig, err := migrate.NewWithInstance("iofs", migDrv, "sqlite3", dbDrv) if err != nil { return nil, err } diff --git a/serve/missing-branch.go.html b/serve/missing-branch.go.html new file mode 100644 index 0000000..4e9be3f --- /dev/null +++ b/serve/missing-branch.go.html @@ -0,0 +1,11 @@ + +
The requested beta is not available
+