mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:37:30 +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) {
|
||||
for _, mapper := range []func(*slog.Logger, *field) Configure{
|
||||
fieldFunctionByImplementation,
|
||||
fieldFunctionByConfigurer,
|
||||
fieldFunctionByIterator,
|
||||
fieldFunctionByReflection,
|
||||
} {
|
||||
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()))
|
||||
}
|
||||
|
||||
func fieldFunctionByImplementation(l *slog.Logger, f *field) Configure {
|
||||
func fieldFunctionByConfigurer(l *slog.Logger, f *field) Configure {
|
||||
if f.value.Type().Implements(reflect.TypeFor[Configurer]()) {
|
||||
l.Debug("field is a custom implementation")
|
||||
return func() (value any, err error) {
|
||||
f.printStructInfo()
|
||||
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/mitchellh/mapstructure"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/cmd/configure/bla4"
|
||||
"github.com/zitadel/zitadel/backend/storage/database"
|
||||
)
|
||||
|
||||
@@ -24,19 +25,38 @@ type Config struct {
|
||||
// Host string
|
||||
// Port int32
|
||||
// Database string
|
||||
// EventPushConnRatio float64
|
||||
// MaxOpenConns uint32
|
||||
// MaxIdleConns uint32
|
||||
// MaxConnLifetime time.Duration
|
||||
// MaxConnIdleTime time.Duration
|
||||
// User User
|
||||
// Admin AdminUser
|
||||
// // Additional options to be appended as options=<Options>
|
||||
// // The value will be taken as is. Multiple options are space separated.
|
||||
// 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) {
|
||||
typeSelect := promptui.Select{
|
||||
Label: "Configure the database connection",
|
||||
@@ -67,6 +87,8 @@ func (c *Config) Configure() (value any, err error) {
|
||||
return prompt.Run()
|
||||
}
|
||||
|
||||
var _ bla4.Iterator = (*Config)(nil)
|
||||
|
||||
// Connect implements [database.Connector].
|
||||
func (c *Config) Connect(ctx context.Context) (database.Pool, error) {
|
||||
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
|
||||
}
|
||||
|
||||
row := tx.QueryRow(stateQuery, currentState.instanceID, h.projection.Name())
|
||||
row := tx.QueryRowContext(ctx, stateQuery, currentState.instanceID, h.projection.Name())
|
||||
err = row.Scan(
|
||||
aggregateID,
|
||||
aggregateType,
|
||||
|
Reference in New Issue
Block a user