package command import ( "context" "github.com/jackc/pgx/v4/pgxpool" "forge.cadoles.com/Cadoles/daddy/internal/database" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/cqrs" "gitlab.com/wpetit/goweb/middleware/container" ) const ( createConnectedUserStatement = ` INSERT INTO users (email, connected_at) VALUES ($1, now()) ON CONFLICT ON CONSTRAINT unique_email DO UPDATE SET connected_at = now(); ` createUserStatement = ` INSERT INTO users (email) VALUES ($1) ON CONFLICT ON CONSTRAINT unique_email DO NOTHING; ` ) type CreateUserCommandRequest struct { Email string Connected bool } func HandleCreateUserCommand(ctx context.Context, cmd cqrs.Command) error { req, ok := cmd.Request().(*CreateUserCommandRequest) if !ok { return errors.WithStack(cqrs.ErrUnexpectedRequest) } ctn, err := container.From(ctx) if err != nil { return errors.WithStack(err) } pool, err := database.From(ctn) if err != nil { return errors.WithStack(err) } conn, err := pool.Acquire(ctx) if err != nil { return errors.WithStack(err) } defer conn.Release() if req.Connected { if err := createConnectedUser(ctx, conn, req.Email); err != nil { return errors.WithStack(err) } } else { if err := createUser(ctx, conn, req.Email); err != nil { return errors.WithStack(err) } } return nil } func createConnectedUser(ctx context.Context, conn *pgxpool.Conn, email string) error { _, err := conn.Conn().Prepare( ctx, "create_connected_user", createConnectedUserStatement, ) if err != nil { return errors.WithStack(err) } if _, err := conn.Exec(ctx, "create_connected_user", email); err != nil { return errors.WithStack(err) } return nil } func createUser(ctx context.Context, conn *pgxpool.Conn, email string) error { _, err := conn.Conn().Prepare( ctx, "create_user", createUserStatement, ) if err != nil { return errors.WithStack(err) } if _, err := conn.Exec(ctx, "create_user", email); err != nil { return errors.WithStack(err) } return nil }