mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:47:32 +00:00
alles en scheiss
This commit is contained in:
70
backend/cmd/configure/bla4/iterator.go
Normal file
70
backend/cmd/configure/bla4/iterator.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package bla4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/manifoldco/promptui"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Iterator interface {
|
||||||
|
// NextField returns the name of the next field to configure.
|
||||||
|
// If it returns an empty string, the configuration is complete.
|
||||||
|
NextField() string
|
||||||
|
// FinishAllowed returns true if the configuration is complete and the user can skip the remaining fields.
|
||||||
|
FinishAllowed() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func fieldFunctionByIterator(l *slog.Logger, f *field) Configure {
|
||||||
|
if !f.value.Type().Implements(reflect.TypeFor[Iterator]()) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return func() (value any, err error) {
|
||||||
|
iter := f.value.Interface().(Iterator)
|
||||||
|
sub := f.sub()
|
||||||
|
for {
|
||||||
|
fieldName := iter.NextField()
|
||||||
|
if fieldName == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if iter.FinishAllowed() {
|
||||||
|
prompt := promptui.Prompt{
|
||||||
|
Label: fmt.Sprintf("Finish configuration of %s", f.info.Name),
|
||||||
|
IsConfirm: true,
|
||||||
|
}
|
||||||
|
_, err := prompt.Run()
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info, ok := f.value.Type().FieldByName(fieldName)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("field %s not found", fieldName)
|
||||||
|
}
|
||||||
|
tag, err := newTag(info, f.value.FieldByName(fieldName))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if tag.skip {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := fieldFunction(
|
||||||
|
l.With(slog.String("field", fieldName)),
|
||||||
|
&field{
|
||||||
|
info: info,
|
||||||
|
viper: sub, //TODO: sub of sub
|
||||||
|
tag: tag,
|
||||||
|
},
|
||||||
|
)()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
reflect.Indirect(f.value).FieldByName(fieldName).Set(reflect.ValueOf(res))
|
||||||
|
}
|
||||||
|
f.viper.Set(f.tag.fieldName, sub.AllSettings())
|
||||||
|
return value, err
|
||||||
|
}
|
||||||
|
}
|
@@ -88,7 +88,8 @@ func structToConfigureMap(l *slog.Logger, v *viper.Viper, object reflect.Value)
|
|||||||
|
|
||||||
func fieldFunction(l *slog.Logger, f *field) (configure Configure) {
|
func fieldFunction(l *slog.Logger, f *field) (configure Configure) {
|
||||||
for _, mapper := range []func(*slog.Logger, *field) Configure{
|
for _, mapper := range []func(*slog.Logger, *field) Configure{
|
||||||
fieldFunctionByImplementation,
|
fieldFunctionByConfigurer,
|
||||||
|
fieldFunctionByIterator,
|
||||||
fieldFunctionByReflection,
|
fieldFunctionByReflection,
|
||||||
} {
|
} {
|
||||||
if configure = mapper(l, f); configure != nil {
|
if configure = mapper(l, f); configure != nil {
|
||||||
@@ -98,9 +99,8 @@ func fieldFunction(l *slog.Logger, f *field) (configure Configure) {
|
|||||||
panic(fmt.Sprintf("unsupported field type: %s", f.info.Type.String()))
|
panic(fmt.Sprintf("unsupported field type: %s", f.info.Type.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func fieldFunctionByImplementation(l *slog.Logger, f *field) Configure {
|
func fieldFunctionByConfigurer(l *slog.Logger, f *field) Configure {
|
||||||
if f.value.Type().Implements(reflect.TypeFor[Configurer]()) {
|
if f.value.Type().Implements(reflect.TypeFor[Configurer]()) {
|
||||||
l.Debug("field is a custom implementation")
|
|
||||||
return func() (value any, err error) {
|
return func() (value any, err error) {
|
||||||
f.printStructInfo()
|
f.printStructInfo()
|
||||||
res, err := f.value.Interface().(Configurer).Configure()
|
res, err := f.value.Interface().(Configurer).Configure()
|
||||||
|
74
backend/cmd/configure/bla5/update_config8.go
Normal file
74
backend/cmd/configure/bla5/update_config8.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package bla5
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
||||||
|
AddSource: true,
|
||||||
|
Level: slog.LevelDebug,
|
||||||
|
}))
|
||||||
|
|
||||||
|
type Configure func() (value any, err error)
|
||||||
|
|
||||||
|
type Configurer interface {
|
||||||
|
// Configure is called to configure the value.
|
||||||
|
// It must return the same type as itself. Otherwise [Update] will panic because it is not able to set the value.
|
||||||
|
Configure() (value any, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Update(v *viper.Viper, config any) func(cmd *cobra.Command, args []string) {
|
||||||
|
return func(cmd *cobra.Command, args []string) {
|
||||||
|
value := reflect.ValueOf(config)
|
||||||
|
structConfigures := structToConfigureMap(Logger, v, value)
|
||||||
|
for key, configure := range structConfigures {
|
||||||
|
result, err := configure()
|
||||||
|
if err != nil {
|
||||||
|
Logger.Error("error configuring field", slog.String("field", key), slog.Any("cause", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
value.Elem().FieldByName(key).Set(reflect.ValueOf(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
err := v.WriteConfig()
|
||||||
|
if err != nil {
|
||||||
|
Logger.Error("error writing config", slog.Any("cause", err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func objectToFlow(l *slog.Logger, value reflect.Value) {
|
||||||
|
if value.Kind() == reflect.Pointer {
|
||||||
|
if value.IsNil() {
|
||||||
|
value = reflect.New(value.Type().Elem())
|
||||||
|
}
|
||||||
|
value = value.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
typeOfValue := value.Type()
|
||||||
|
for i := 0; i < value.NumField(); i++ {
|
||||||
|
fieldValue := value.Field(i)
|
||||||
|
fieldType := typeOfValue.Field(i)
|
||||||
|
|
||||||
|
l.Info("Processing field", slog.String("field", fieldType.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type field struct {
|
||||||
|
set func(value reflect.Value) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type structField struct {
|
||||||
|
name string
|
||||||
|
|
||||||
|
fields []field
|
||||||
|
}
|
||||||
|
|
||||||
|
type primitiveField struct {
|
||||||
|
}
|
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/manifoldco/promptui"
|
"github.com/manifoldco/promptui"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/backend/cmd/configure/bla4"
|
||||||
"github.com/zitadel/zitadel/backend/storage/database"
|
"github.com/zitadel/zitadel/backend/storage/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,19 +25,38 @@ type Config struct {
|
|||||||
// Host string
|
// Host string
|
||||||
// Port int32
|
// Port int32
|
||||||
// Database string
|
// Database string
|
||||||
// EventPushConnRatio float64
|
|
||||||
// MaxOpenConns uint32
|
// MaxOpenConns uint32
|
||||||
// MaxIdleConns uint32
|
// MaxIdleConns uint32
|
||||||
// MaxConnLifetime time.Duration
|
// MaxConnLifetime time.Duration
|
||||||
// MaxConnIdleTime time.Duration
|
// MaxConnIdleTime time.Duration
|
||||||
// User User
|
// User User
|
||||||
// Admin AdminUser
|
|
||||||
// // Additional options to be appended as options=<Options>
|
// // Additional options to be appended as options=<Options>
|
||||||
// // The value will be taken as is. Multiple options are space separated.
|
// // The value will be taken as is. Multiple options are space separated.
|
||||||
// Options string
|
// Options string
|
||||||
|
|
||||||
|
configuredFields []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure implements bla3.Custom.
|
// FinishAllowed implements [bla4.Iterator].
|
||||||
|
func (c *Config) FinishAllowed() bool {
|
||||||
|
// Option can be skipped
|
||||||
|
return len(c.configuredFields) < 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextField implements [bla4.Iterator].
|
||||||
|
func (c *Config) NextField() string {
|
||||||
|
if c.configuredFields == nil {
|
||||||
|
c.configuredFields = []string{"Host", "Port", "Database", "MaxOpenConns", "MaxIdleConns", "MaxConnLifetime", "MaxConnIdleTime", "User", "Options"}
|
||||||
|
}
|
||||||
|
if len(c.configuredFields) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
field := c.configuredFields[0]
|
||||||
|
c.configuredFields = c.configuredFields[1:]
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure implements [bla4.Configurer].
|
||||||
func (c *Config) Configure() (value any, err error) {
|
func (c *Config) Configure() (value any, err error) {
|
||||||
typeSelect := promptui.Select{
|
typeSelect := promptui.Select{
|
||||||
Label: "Configure the database connection",
|
Label: "Configure the database connection",
|
||||||
@@ -67,6 +87,8 @@ func (c *Config) Configure() (value any, err error) {
|
|||||||
return prompt.Run()
|
return prompt.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ bla4.Iterator = (*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)
|
||||||
|
@@ -54,7 +54,7 @@ func (h *Handler) currentState(ctx context.Context, tx *sql.Tx, config *triggerC
|
|||||||
stateQuery = currentStateAwaitStmt
|
stateQuery = currentStateAwaitStmt
|
||||||
}
|
}
|
||||||
|
|
||||||
row := tx.QueryRow(stateQuery, currentState.instanceID, h.projection.Name())
|
row := tx.QueryRowContext(ctx, stateQuery, currentState.instanceID, h.projection.Name())
|
||||||
err = row.Scan(
|
err = row.Scan(
|
||||||
aggregateID,
|
aggregateID,
|
||||||
aggregateType,
|
aggregateType,
|
||||||
|
Reference in New Issue
Block a user