some ideas

This commit is contained in:
adlerhurst
2025-03-04 20:00:09 +01:00
parent 8f0ca7b2cd
commit b093112063
10 changed files with 165 additions and 122 deletions

View File

@@ -114,6 +114,10 @@ func handleField(v *viper.Viper, field reflect.StructField, value reflect.Value)
value = reflect.Indirect(value) value = reflect.Indirect(value)
if value.IsZero() {
value = reflect.New(value.Type()).Elem()
}
// Check if potential non pointer value implements [OneOfField] // Check if potential non pointer value implements [OneOfField]
if value.Type().Implements(reflect.TypeFor[OneOfField]()) { if value.Type().Implements(reflect.TypeFor[OneOfField]()) {
return handleOneOf(v, field, value, fieldConfig) return handleOneOf(v, field, value, fieldConfig)

View File

@@ -0,0 +1,70 @@
package bla2
import (
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
type TestConfig struct {
API APIConfig `configure:""`
Database DatabaseOneOf `configure:"type=oneof"`
}
type APIConfig struct {
Host string `configure:""`
Port uint16 `configure:""`
}
type DatabaseOneOf struct {
ConnectionString *string `configure:""`
Config *DatabaseConfig `configure:""`
}
type DatabaseConfig struct {
Host string `configure:""`
Port uint16 `configure:""`
SSLMode string `configure:""`
}
type Config interface {
Hooks() []viper.DecoderConfigOption
}
func Update(v *viper.Viper, config any) func(cmd *cobra.Command, args []string) {
return func(cmd *cobra.Command, args []string) {
// promptui.Select
// err := handleStruct(v, reflect.ValueOf(config), configuration{})
// if err != nil {
// fmt.Println(err)
// os.Exit(1)
// }
// err = v.WriteConfig()
// if err != nil {
// fmt.Println(err)
// os.Exit(1)
// }
}
}
const (
tagName = "configure"
defaultKey = "default"
oneOfKey = "oneof"
)
type Field struct {
Name string
DefaultValue any
Prompt prompt
}
type prompt interface {
Run()
}
var (
_ prompt = (*promptui.Select)(nil)
_ prompt = (*promptui.SelectWithAdd)(nil)
_ prompt = (*promptui.Prompt)(nil)
)

View File

@@ -17,7 +17,7 @@ var (
) )
type Step001 struct { type Step001 struct {
Database database.Pool `mapstructure:"-"` Database database.Pool `mapstructure:"-" configure:"-"`
DatabaseName string `configure:"default=zitadel"` DatabaseName string `configure:"default=zitadel"`
Username string `configure:"default=zitadel"` Username string `configure:"default=zitadel"`

View File

@@ -1,12 +1,12 @@
package prepare package prepare
import ( import (
"github.com/Masterminds/semver/v3"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/zitadel/zitadel/backend/cmd/config" "github.com/zitadel/zitadel/backend/cmd/config"
"github.com/zitadel/zitadel/backend/cmd/configure" "github.com/zitadel/zitadel/backend/cmd/configure"
"github.com/zitadel/zitadel/backend/cmd/configure/bla"
step001 "github.com/zitadel/zitadel/backend/cmd/prepare/001" step001 "github.com/zitadel/zitadel/backend/cmd/prepare/001"
"github.com/zitadel/zitadel/backend/storage/database" "github.com/zitadel/zitadel/backend/storage/database"
"github.com/zitadel/zitadel/backend/storage/database/dialect" "github.com/zitadel/zitadel/backend/storage/database/dialect"
@@ -36,62 +36,24 @@ var (
// panic(err) // panic(err)
// } // }
// }, // },
Run: configure.Update( // Run: configure.Update(
"prepare", // "prepare",
"Writes the configuration for the prepare command", // "Writes the configuration for the prepare command",
configuration.Fields(), // configuration.Fields(),
), // ),
Run: bla.Update(viper.GetViper(), &configuration),
PreRun: configure.ReadConfigPreRun(viper.GetViper(), &configuration), PreRun: configure.ReadConfigPreRun(viper.GetViper(), &configuration),
} }
) )
type Config struct { type Config struct {
config.Config `mapstructure:",squash"` config.Config `mapstructure:",squash" configure:"-"`
Database dialect.Config Database dialect.Config // `configure:"-"`
Step001 step001.Step001 Step001 step001.Step001
// runtime config // runtime config
Client database.Pool `mapstructure:"-"` Client database.Pool `mapstructure:"-" configure:"-"`
}
// Describe implements configure.StructUpdater.
func (c *Config) Describe() string {
return "Configuration for the prepare command"
}
// Name implements configure.StructUpdater.
func (c *Config) Name() string {
return "prepare"
}
// ShouldUpdate implements configure.StructUpdater.
func (c *Config) ShouldUpdate(version *semver.Version) bool {
if version == nil {
return true
}
for _, field := range c.Fields() {
if field.ShouldUpdate(version) {
return true
}
}
return false
}
// Fields implements configure.UpdateConfig.
func (c Config) Fields() []configure.Updater {
return []configure.Updater{
&configure.Struct{
FieldName: "step001",
Description: "The configuration for the first step of the prepare command",
SubFields: c.Step001.Fields(),
},
&configure.Struct{
FieldName: "database",
Description: "The configuration for the database connection",
SubFields: c.Database.Fields(),
},
}
} }
func (c *Config) Hooks() (decoders []viper.DecoderConfigOption) { func (c *Config) Hooks() (decoders []viper.DecoderConfigOption) {

View File

@@ -18,11 +18,11 @@ var (
// This application is a tool to generate the needed files // This application is a tool to generate the needed files
// to quickly create a Cobra application.`, // to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
var err error // var err error
configuration.Client, err = configuration.Database.Connect(cmd.Context()) // configuration.Client, err = configuration.Database.Connect(cmd.Context())
if err != nil { // if err != nil {
panic(err) // panic(err)
} // }
defer configuration.Client.Close(cmd.Context()) defer configuration.Client.Close(cmd.Context())
if err := (&step001.Step001{Database: configuration.Client}).Migrate(cmd.Context()); err != nil { if err := (&step001.Step001{Database: configuration.Client}).Migrate(cmd.Context()); err != nil {
panic(err) panic(err)

View File

@@ -2,5 +2,5 @@ configuredversion: 2025.2.23
database: database:
postgres: host=local postgres: host=local
step001: step001:
databasename: zita databasename: asdf
username: adel username: asdf

View File

@@ -3,7 +3,6 @@ package dialect
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"reflect" "reflect"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
@@ -11,6 +10,7 @@ import (
"github.com/zitadel/zitadel/backend/cmd/config" "github.com/zitadel/zitadel/backend/cmd/config"
"github.com/zitadel/zitadel/backend/cmd/configure" "github.com/zitadel/zitadel/backend/cmd/configure"
"github.com/zitadel/zitadel/backend/cmd/configure/bla"
"github.com/zitadel/zitadel/backend/storage/database" "github.com/zitadel/zitadel/backend/storage/database"
"github.com/zitadel/zitadel/backend/storage/database/dialect/gosql" "github.com/zitadel/zitadel/backend/storage/database/dialect/gosql"
"github.com/zitadel/zitadel/backend/storage/database/dialect/postgres" "github.com/zitadel/zitadel/backend/storage/database/dialect/postgres"
@@ -21,60 +21,32 @@ type Hook struct {
Decode func(name string, config any) (database.Connector, error) Decode func(name string, config any) (database.Connector, error)
Name string Name string
Field configure.Updater Field configure.Updater
Constructor func() any
} }
var hooks = make([]Hook, 0) var hooks = []Hook{
{
func init() {
hooks = append(hooks,
Hook{
Match: postgres.NameMatcher, Match: postgres.NameMatcher,
Decode: postgres.DecodeConfig, Decode: postgres.DecodeConfig,
Name: postgres.Name, Name: postgres.Name,
Field: postgres.Field, Field: postgres.Field,
Constructor: func() any { return new(postgres.Config) },
}, },
Hook{ {
Match: gosql.NameMatcher, Match: gosql.NameMatcher,
Decode: gosql.DecodeConfig, Decode: gosql.DecodeConfig,
Name: gosql.Name, Name: gosql.Name,
Field: gosql.Field, Field: gosql.Field,
Constructor: func() any { return new(gosql.Config) },
}, },
)
} }
type Config struct { type Config struct {
Dialects map[string]any `mapstructure:",remain"` Dialects dialects `mapstructure:",remain"`
connector database.Connector connector database.Connector
} }
// Fields implements [configure.StructUpdater].
func (c *Config) Fields() []configure.Updater {
dialects := configure.OneOf{
Description: "The database dialect Zitadel connects to",
SubFields: []configure.Updater{},
}
for _, hook := range hooks {
if hook.Field == nil {
panic("hook must configure its config fields")
}
dialects.SubFields = append(dialects.SubFields, &configure.Struct{
FieldName: hook.Name,
Description: fmt.Sprintf("Configuration for %s", hook.Name),
SubFields: []configure.Updater{hook.Field},
})
}
return []configure.Updater{
dialects,
}
}
// Name implements [configure.StructUpdater].
func (c *Config) Name() string {
return "database"
}
func (c Config) Connect(ctx context.Context) (database.Pool, error) { func (c Config) Connect(ctx context.Context) (database.Pool, error) {
if len(c.Dialects) != 1 { if len(c.Dialects) != 1 {
return nil, errors.New("Exactly one dialect must be configured") return nil, errors.New("Exactly one dialect must be configured")
@@ -131,3 +103,21 @@ func decodeHook(from, to reflect.Value) (_ interface{}, err error) {
return config, nil return config, nil
} }
type dialects map[string]any
// ConfigForIndex implements [bla.OneOfField].
func (d dialects) ConfigForIndex(i int) any {
return hooks[i].Constructor()
}
// Possibilities implements [bla.OneOfField].
func (d dialects) Possibilities() []string {
possibilities := make([]string, len(hooks))
for i, hook := range hooks {
possibilities[i] = hook.Name
}
return possibilities
}
var _ bla.OneOfField = (dialects)(nil)

View File

@@ -10,6 +10,7 @@ import (
"github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/pgxpool"
"github.com/zitadel/zitadel/backend/cmd/configure" "github.com/zitadel/zitadel/backend/cmd/configure"
"github.com/zitadel/zitadel/backend/cmd/configure/bla"
"github.com/zitadel/zitadel/backend/storage/database" "github.com/zitadel/zitadel/backend/storage/database"
) )
@@ -93,11 +94,29 @@ var (
} }
) )
type Config struct{ *pgxpool.Config } type Config struct{ pgxpool.Config }
// ConfigForIndex implements bla.OneOfField.
func (c Config) ConfigForIndex(i int) any {
switch i {
case 0:
return new(string)
case 1:
return &c.Config
}
return nil
}
// Possibilities implements bla.OneOfField.
func (c Config) Possibilities() []string {
return []string{"connection string", "fields"}
}
var _ bla.OneOfField = (*Config)(nil)
// Connect implements [database.Connector]. // Connect implements [database.Connector].
func (c *Config) Connect(ctx context.Context) (database.Pool, error) { func (c *Config) Connect(ctx context.Context) (database.Pool, error) {
pool, err := pgxpool.NewWithConfig(ctx, c.Config) pool, err := pgxpool.NewWithConfig(ctx, &c.Config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -118,10 +137,10 @@ func DecodeConfig(_ string, config any) (database.Connector, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Config{config}, nil return &Config{Config: *config}, nil
case map[string]any: case map[string]any:
return &Config{ return &Config{
Config: &pgxpool.Config{}, Config: pgxpool.Config{},
}, nil }, nil
} }
return nil, errors.New("invalid configuration") return nil, errors.New("invalid configuration")

9
go.mod
View File

@@ -8,6 +8,7 @@ require (
github.com/BurntSushi/toml v1.4.0 github.com/BurntSushi/toml v1.4.0
github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.24.0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.24.0
github.com/Masterminds/semver/v3 v3.3.1
github.com/Masterminds/squirrel v1.5.4 github.com/Masterminds/squirrel v1.5.4
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b
github.com/alecthomas/participle/v2 v2.1.1 github.com/alecthomas/participle/v2 v2.1.1
@@ -47,6 +48,7 @@ require (
github.com/jinzhu/gorm v1.9.16 github.com/jinzhu/gorm v1.9.16
github.com/k3a/html2text v1.2.1 github.com/k3a/html2text v1.2.1
github.com/lucasb-eyer/go-colorful v1.2.0 github.com/lucasb-eyer/go-colorful v1.2.0
github.com/manifoldco/promptui v0.9.0
github.com/minio/minio-go/v7 v7.0.73 github.com/minio/minio-go/v7 v7.0.73
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
github.com/muesli/gamut v0.3.1 github.com/muesli/gamut v0.3.1
@@ -57,6 +59,8 @@ require (
github.com/pquerna/otp v1.4.0 github.com/pquerna/otp v1.4.0
github.com/rakyll/statik v0.1.7 github.com/rakyll/statik v0.1.7
github.com/redis/go-redis/v9 v9.7.0 github.com/redis/go-redis/v9 v9.7.0
github.com/riverqueue/river v0.16.0
github.com/riverqueue/river/riverdriver v0.16.0
github.com/rs/cors v1.11.1 github.com/rs/cors v1.11.1
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/sony/gobreaker/v2 v2.0.0 github.com/sony/gobreaker/v2 v2.0.0
@@ -100,7 +104,6 @@ require (
cloud.google.com/go/auth v0.6.1 // indirect cloud.google.com/go/auth v0.6.1 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0 // indirect
github.com/Masterminds/semver/v3 v3.3.1 // indirect
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
github.com/chzyer/readline v1.5.1 // indirect github.com/chzyer/readline v1.5.1 // indirect
@@ -120,15 +123,12 @@ require (
github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/lib/pq v1.10.9 // indirect github.com/lib/pq v1.10.9 // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/riverqueue/river v0.16.0 // indirect
github.com/riverqueue/river/riverdriver v0.16.0 // indirect
github.com/riverqueue/river/rivershared v0.16.0 // indirect github.com/riverqueue/river/rivershared v0.16.0 // indirect
github.com/riverqueue/river/rivertype v0.16.0 // indirect github.com/riverqueue/river/rivertype v0.16.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect
@@ -140,7 +140,6 @@ require (
github.com/tidwall/sjson v1.2.5 // indirect github.com/tidwall/sjson v1.2.5 // indirect
github.com/yuin/gopher-lua v1.1.1 // indirect github.com/yuin/gopher-lua v1.1.1 // indirect
github.com/zenazn/goji v1.0.1 // indirect github.com/zenazn/goji v1.0.1 // indirect
go.uber.org/goleak v1.3.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d // indirect google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d // indirect

13
go.sum
View File

@@ -113,11 +113,13 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -425,16 +427,14 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
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 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= 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 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.0 h1:FG6VLIdzvAPhnYqP14sQ2xhFLkiUQHCs6ySqO91kF4g=
github.com/jackc/pgx/v5 v5.7.0/go.mod h1:awP1KNnjylvpxHuHP63gzjhnGkI1iw+PMoIwvoleN/8=
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI= 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/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= 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/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 h1:jny9eqYPwkG8IVy7foUoRjQmFLcArCSz+uPsL6KS0HQ= github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 h1:jny9eqYPwkG8IVy7foUoRjQmFLcArCSz+uPsL6KS0HQ=
@@ -659,6 +659,8 @@ github.com/riverqueue/river v0.16.0 h1:YyQrs0kGgjuABwgat02DPUYS0TMyG2ZFlzvf6+fSF
github.com/riverqueue/river v0.16.0/go.mod h1:pEZ8Gc15XyFjVY89nJeL256ub5z18XF7ukYn8ktqQrs= github.com/riverqueue/river v0.16.0/go.mod h1:pEZ8Gc15XyFjVY89nJeL256ub5z18XF7ukYn8ktqQrs=
github.com/riverqueue/river/riverdriver v0.16.0 h1:y4Df4e1Xk3Id0nnu1VxHJn9118OzmRHcmvOxM/i1Q30= github.com/riverqueue/river/riverdriver v0.16.0 h1:y4Df4e1Xk3Id0nnu1VxHJn9118OzmRHcmvOxM/i1Q30=
github.com/riverqueue/river/riverdriver v0.16.0/go.mod h1:7Kdf5HQDrLyLUUqPqXobaK+7zbcMctWeAl7yhg4nHes= github.com/riverqueue/river/riverdriver v0.16.0/go.mod h1:7Kdf5HQDrLyLUUqPqXobaK+7zbcMctWeAl7yhg4nHes=
github.com/riverqueue/river/riverdriver/riverdatabasesql v0.16.0 h1:T/DcMmZXiJAyLN3CSyAoNcf3U4oAD9Ht/8Vd5SXv5YU=
github.com/riverqueue/river/riverdriver/riverdatabasesql v0.16.0/go.mod h1:a9EUhD2yGsAeM9eWo+QrGGbL8LVWoGj2m8KEzm0xUxE=
github.com/riverqueue/river/riverdriver/riverpgxv5 v0.16.0 h1:6HP296OPN+3ORL9qG1f561pldB5eovkLzfkNIQmaTXI= github.com/riverqueue/river/riverdriver/riverpgxv5 v0.16.0 h1:6HP296OPN+3ORL9qG1f561pldB5eovkLzfkNIQmaTXI=
github.com/riverqueue/river/riverdriver/riverpgxv5 v0.16.0/go.mod h1:MAeBNoTQ+CD3nRvV9mF6iCBfsGJTxYHZeZSP4MYoeUE= github.com/riverqueue/river/riverdriver/riverpgxv5 v0.16.0/go.mod h1:MAeBNoTQ+CD3nRvV9mF6iCBfsGJTxYHZeZSP4MYoeUE=
github.com/riverqueue/river/rivershared v0.16.0 h1:L1lQ3gMwdIsxA6yF0/PwAdsFP0T82yBD1V03q2GuJDU= github.com/riverqueue/river/rivershared v0.16.0 h1:L1lQ3gMwdIsxA6yF0/PwAdsFP0T82yBD1V03q2GuJDU=
@@ -738,7 +740,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
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= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@@ -935,8 +936,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=