diff --git a/backend/controller/controller.go b/backend/controller/controller.go index 85cbb4417b..2201745607 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -41,12 +41,13 @@ import ( "github.com/TBD54566975/ftl/backend/controller/dal" "github.com/TBD54566975/ftl/backend/controller/ingress" "github.com/TBD54566975/ftl/backend/controller/leases" + leasesdal "github.com/TBD54566975/ftl/backend/controller/leases/dal" "github.com/TBD54566975/ftl/backend/controller/observability" "github.com/TBD54566975/ftl/backend/controller/pubsub" "github.com/TBD54566975/ftl/backend/controller/scaling" "github.com/TBD54566975/ftl/backend/controller/scaling/localscaling" "github.com/TBD54566975/ftl/backend/controller/scheduledtask" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/console/pbconsoleconnect" "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" @@ -194,6 +195,7 @@ type ControllerListListener interface { type Service struct { conn *sql.DB + leasesdal *leasesdal.DAL dal *dal.DAL key model.ControllerKey deploymentLogsSink *deploymentLogsSink @@ -231,14 +233,16 @@ func New(ctx context.Context, conn *sql.DB, config Config, runnerScaling scaling config.ControllerTimeout = time.Second * 5 } + ldb := leasesdal.New(conn) db, err := dal.New(ctx, conn, encryption.NewBuilder().WithKMSURI(optional.Ptr(config.KMSURI))) if err != nil { return nil, fmt.Errorf("failed to create DAL: %w", err) } svc := &Service{ - tasks: scheduledtask.New(ctx, key, db), + tasks: scheduledtask.New(ctx, key, ldb), dal: db, + leasesdal: ldb, conn: conn, key: key, deploymentLogsSink: newDeploymentLogsSink(ctx, db), @@ -307,7 +311,7 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { routes, err := s.dal.GetIngressRoutes(r.Context(), r.Method) if err != nil { - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { http.NotFound(w, r) observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.None[*schemapb.Ref](), start, optional.Some("route not found in dal")) return @@ -509,7 +513,7 @@ func (s *Service) UpdateDeploy(ctx context.Context, req *connect.Request[ftlv1.U err = s.dal.SetDeploymentReplicas(ctx, deploymentKey, int(req.Msg.MinReplicas)) if err != nil { - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { logger.Errorf(err, "Deployment not found: %s", deploymentKey) return nil, connect.NewError(connect.CodeNotFound, errors.New("deployment not found")) } @@ -531,7 +535,7 @@ func (s *Service) ReplaceDeploy(ctx context.Context, c *connect.Request[ftlv1.Re err = s.dal.ReplaceDeployment(ctx, newDeploymentKey, int(c.Msg.MinReplicas)) if err != nil { - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { logger.Errorf(err, "Deployment not found: %s", newDeploymentKey) return nil, connect.NewError(connect.CodeNotFound, errors.New("deployment not found")) } else if errors.Is(err, dal.ErrReplaceDeploymentAlreadyActive) { @@ -591,7 +595,7 @@ func (s *Service) RegisterRunner(ctx context.Context, stream *connect.ClientStre Deployment: maybeDeployment, Labels: msg.Labels.AsMap(), }) - if errors.Is(err, dalerrs.ErrConflict) { + if errors.Is(err, libdal.ErrConflict) { return nil, connect.NewError(connect.CodeAlreadyExists, err) } else if err != nil { return nil, err @@ -608,7 +612,7 @@ func (s *Service) RegisterRunner(ctx context.Context, stream *connect.ClientStre } routes, err := s.dal.GetRoutingTable(ctx, nil) - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { routes = map[string][]dal.Route{} } else if err != nil { return nil, err @@ -815,7 +819,7 @@ func (s *Service) AcquireLease(ctx context.Context, stream *connect.BidiStream[f return connect.NewError(connect.CodeInternal, fmt.Errorf("could not receive lease request: %w", err)) } if lease == nil { - lease, _, err = s.dal.AcquireLease(ctx, leases.ModuleKey(msg.Module, msg.Key...), msg.Ttl.AsDuration(), optional.None[any]()) + lease, _, err = s.leasesdal.AcquireLease(ctx, leases.ModuleKey(msg.Module, msg.Key...), msg.Ttl.AsDuration(), optional.None[any]()) if err != nil { if errors.Is(err, leases.ErrConflict) { return connect.NewError(connect.CodeResourceExhausted, fmt.Errorf("lease is held: %w", err)) @@ -948,7 +952,7 @@ func (s *Service) SetNextFSMEvent(ctx context.Context, req *connect.Request[ftlv // Get the current state the instance is transitioning to. _, currentDestinationState, err := tx.GetFSMStates(ctx, fsmKey, req.Msg.Instance) if err != nil { - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("fsm instance not found: %w", err)) } return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("could not get fsm instance: %w", err)) @@ -963,7 +967,7 @@ func (s *Service) SetNextFSMEvent(ctx context.Context, req *connect.Request[ftlv // Set the next event. err = tx.SetNextFSMEvent(ctx, fsmKey, msg.Instance, nextState.ToRefKey(), msg.Body, eventType) if err != nil { - if errors.Is(err, dalerrs.ErrConflict) { + if errors.Is(err, libdal.ErrConflict) { return nil, connect.NewError(connect.CodeFailedPrecondition, fmt.Errorf("fsm instance already has its next state set: %w", err)) } return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("could not set next fsm event: %w", err)) @@ -1403,7 +1407,7 @@ func (s *Service) executeAsyncCalls(ctx context.Context) (interval time.Duration logger.Tracef("Acquiring async call") call, leaseCtx, err := s.dal.AcquireAsyncCall(ctx) - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { logger.Tracef("No async calls to execute") return time.Second * 2, nil } else if err != nil { @@ -1740,7 +1744,7 @@ func (s *Service) resolveFSMEvent(msg *ftlv1.SendFSMEventRequest) (fsm *schema.F } func (s *Service) expireStaleLeases(ctx context.Context) (time.Duration, error) { - err := s.dal.ExpireLeases(ctx) + err := s.leasesdal.ExpireLeases(ctx) if err != nil { return 0, fmt.Errorf("failed to expire leases: %w", err) } @@ -1972,7 +1976,7 @@ func (s *Service) getDeploymentLogger(ctx context.Context, deploymentKey model.D // Periodically sync the routing table from the DB. func (s *Service) syncRoutes(ctx context.Context) (time.Duration, error) { routes, err := s.dal.GetRoutingTable(ctx, nil) - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { routes = map[string][]dal.Route{} } else if err != nil { return 0, err diff --git a/backend/controller/cronjobs/cronjobs_test.go b/backend/controller/cronjobs/cronjobs_test.go index 98132b604e..9d65dd5729 100644 --- a/backend/controller/cronjobs/cronjobs_test.go +++ b/backend/controller/cronjobs/cronjobs_test.go @@ -14,7 +14,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/cronjobs/dal" parentdal "github.com/TBD54566975/ftl/backend/controller/dal" "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/cron" "github.com/TBD54566975/ftl/internal/encryption" @@ -57,7 +57,7 @@ func TestNewCronJobsForModule(t *testing.T) { // No async calls yet _, _, err = parentDAL.AcquireAsyncCall(ctx) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) assert.EqualError(t, err, "no pending async calls: not found") err = cjs.scheduleCronJobs(ctx) diff --git a/backend/controller/cronjobs/dal/dal.go b/backend/controller/cronjobs/dal/dal.go index ada64fa446..c2679c8ab0 100644 --- a/backend/controller/cronjobs/dal/dal.go +++ b/backend/controller/cronjobs/dal/dal.go @@ -9,21 +9,21 @@ import ( "github.com/TBD54566975/ftl/backend/controller/cronjobs/sql" "github.com/TBD54566975/ftl/backend/controller/observability" - "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/model" "github.com/TBD54566975/ftl/internal/slices" ) type DAL struct { - *dal.Handle[DAL] + *libdal.Handle[DAL] db sql.Querier } -func New(conn dal.Connection) *DAL { +func New(conn libdal.Connection) *DAL { return &DAL{ db: sql.New(conn), - Handle: dal.New(conn, func(h *dal.Handle[DAL]) *DAL { + Handle: libdal.New(conn, func(h *libdal.Handle[DAL]) *DAL { return &DAL{Handle: h, db: sql.New(h.Connection)} }), } @@ -45,7 +45,7 @@ func cronJobFromRow(c sql.CronJob, d sql.Deployment) model.CronJob { func (d *DAL) CreateAsyncCall(ctx context.Context, params sql.CreateAsyncCallParams) (int64, error) { id, err := d.db.CreateAsyncCall(ctx, params) if err != nil { - return 0, fmt.Errorf("failed to create async call: %w", dal.TranslatePGError(err)) + return 0, fmt.Errorf("failed to create async call: %w", libdal.TranslatePGError(err)) } observability.AsyncCalls.Created(ctx, params.Verb, optional.None[schema.RefKey](), params.Origin, 0, err) queueDepth, err := d.db.AsyncCallQueueDepth(ctx) @@ -62,7 +62,7 @@ func (d *DAL) CreateAsyncCall(ctx context.Context, params sql.CreateAsyncCallPar func (d *DAL) GetUnscheduledCronJobs(ctx context.Context, startTime time.Time) ([]model.CronJob, error) { rows, err := d.db.GetUnscheduledCronJobs(ctx, startTime) if err != nil { - return nil, fmt.Errorf("failed to get cron jobs: %w", dal.TranslatePGError(err)) + return nil, fmt.Errorf("failed to get cron jobs: %w", libdal.TranslatePGError(err)) } return slices.Map(rows, func(r sql.GetUnscheduledCronJobsRow) model.CronJob { return cronJobFromRow(r.CronJob, r.Deployment) @@ -73,7 +73,7 @@ func (d *DAL) GetUnscheduledCronJobs(ctx context.Context, startTime time.Time) ( func (d *DAL) GetCronJobByKey(ctx context.Context, key model.CronJobKey) (model.CronJob, error) { row, err := d.db.GetCronJobByKey(ctx, key) if err != nil { - return model.CronJob{}, fmt.Errorf("failed to get cron job %q: %w", key, dal.TranslatePGError(err)) + return model.CronJob{}, fmt.Errorf("failed to get cron job %q: %w", key, libdal.TranslatePGError(err)) } return cronJobFromRow(row.CronJob, row.Deployment), nil } @@ -82,7 +82,7 @@ func (d *DAL) GetCronJobByKey(ctx context.Context, key model.CronJobKey) (model. func (d *DAL) IsCronJobPending(ctx context.Context, key model.CronJobKey, startTime time.Time) (bool, error) { pending, err := d.db.IsCronJobPending(ctx, key, startTime) if err != nil { - return false, fmt.Errorf("failed to check if cron job %q is pending: %w", key, dal.TranslatePGError(err)) + return false, fmt.Errorf("failed to check if cron job %q is pending: %w", key, libdal.TranslatePGError(err)) } return pending, nil } @@ -92,7 +92,7 @@ func (d *DAL) IsCronJobPending(ctx context.Context, key model.CronJobKey, startT func (d *DAL) UpdateCronJobExecution(ctx context.Context, params sql.UpdateCronJobExecutionParams) error { err := d.db.UpdateCronJobExecution(ctx, params) if err != nil { - return fmt.Errorf("failed to update cron job %q: %w", params.Key, dal.TranslatePGError(err)) + return fmt.Errorf("failed to update cron job %q: %w", params.Key, libdal.TranslatePGError(err)) } return nil } diff --git a/backend/controller/cronjobs/sql/models.go b/backend/controller/cronjobs/sql/models.go index 039df94a07..49d53f0d84 100644 --- a/backend/controller/cronjobs/sql/models.go +++ b/backend/controller/cronjobs/sql/models.go @@ -415,7 +415,7 @@ type FsmNextEvent struct { FsmInstanceID int64 NextState schema.RefKey Request []byte - RequestType Type + RequestType sqltypes.Type } type IngressRoute struct { diff --git a/backend/controller/cronjobs/sql/types.go b/backend/controller/cronjobs/sql/types.go index 31097b10c6..e369443cd8 100644 --- a/backend/controller/cronjobs/sql/types.go +++ b/backend/controller/cronjobs/sql/types.go @@ -1,5 +1,5 @@ package sql -import csql "github.com/TBD54566975/ftl/backend/controller/sql" +import "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" -type Type = csql.Type +type Type = sqltypes.Type diff --git a/backend/controller/dal/async_calls.go b/backend/controller/dal/async_calls.go index e9134d5d60..e3300f6402 100644 --- a/backend/controller/dal/async_calls.go +++ b/backend/controller/dal/async_calls.go @@ -12,9 +12,10 @@ import ( "github.com/alecthomas/types/either" "github.com/alecthomas/types/optional" + leasedal "github.com/TBD54566975/ftl/backend/controller/leases/dal" "github.com/TBD54566975/ftl/backend/controller/sql" "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/model" @@ -95,7 +96,7 @@ func ParseAsyncOrigin(origin string) (AsyncOrigin, error) { } type AsyncCall struct { - *Lease // May be nil + *leasedal.Lease // May be nil ID int64 Origin AsyncOrigin Verb schema.RefKey @@ -127,9 +128,9 @@ func (d *DAL) AcquireAsyncCall(ctx context.Context) (call *AsyncCall, leaseCtx c ttl := time.Second * 5 row, err := tx.db.AcquireAsyncCall(ctx, sqltypes.Duration(ttl)) if err != nil { - err = dalerrs.TranslatePGError(err) - if errors.Is(err, dalerrs.ErrNotFound) { - return nil, ctx, fmt.Errorf("no pending async calls: %w", dalerrs.ErrNotFound) + err = libdal.TranslatePGError(err) + if errors.Is(err, libdal.ErrNotFound) { + return nil, ctx, fmt.Errorf("no pending async calls: %w", libdal.ErrNotFound) } return nil, ctx, fmt.Errorf("failed to acquire async call: %w", err) } @@ -143,7 +144,7 @@ func (d *DAL) AcquireAsyncCall(ctx context.Context) (call *AsyncCall, leaseCtx c return nil, ctx, fmt.Errorf("failed to decrypt async call request: %w", err) } - lease, leaseCtx := d.newLease(ctx, row.LeaseKey, row.LeaseIdempotencyKey, ttl) + lease, leaseCtx := d.leasedal.NewLease(ctx, row.LeaseKey, row.LeaseIdempotencyKey, ttl) return &AsyncCall{ ID: row.AsyncCallID, Verb: row.Verb, @@ -177,7 +178,7 @@ func (d *DAL) CompleteAsyncCall(ctx context.Context, case *dbsql.DB: tx, err = d.Begin(ctx) if err != nil { - return false, dalerrs.TranslatePGError(err) //nolint:wrapcheck + return false, libdal.TranslatePGError(err) //nolint:wrapcheck } defer tx.CommitOrRollback(ctx, &err) case *dbsql.Tx: @@ -197,7 +198,7 @@ func (d *DAL) CompleteAsyncCall(ctx context.Context, } _, err = tx.db.SucceedAsyncCall(ctx, optional.Some(encryptedResult), call.ID) if err != nil { - return false, dalerrs.TranslatePGError(err) //nolint:wrapcheck + return false, libdal.TranslatePGError(err) //nolint:wrapcheck } case either.Right[[]byte, string]: // Failure message. @@ -211,7 +212,7 @@ func (d *DAL) CompleteAsyncCall(ctx context.Context, ScheduledAt: time.Now().Add(call.Backoff), }) if err != nil { - return false, dalerrs.TranslatePGError(err) //nolint:wrapcheck + return false, libdal.TranslatePGError(err) //nolint:wrapcheck } isFinalResult = false didScheduleAnotherCall = true @@ -234,14 +235,14 @@ func (d *DAL) CompleteAsyncCall(ctx context.Context, OriginalError: optional.Some(originalError), }) if err != nil { - return false, dalerrs.TranslatePGError(err) //nolint:wrapcheck + return false, libdal.TranslatePGError(err) //nolint:wrapcheck } isFinalResult = false didScheduleAnotherCall = true } else { _, err = tx.db.FailAsyncCall(ctx, result.Get(), call.ID) if err != nil { - return false, dalerrs.TranslatePGError(err) //nolint:wrapcheck + return false, libdal.TranslatePGError(err) //nolint:wrapcheck } } } @@ -254,7 +255,7 @@ func (d *DAL) CompleteAsyncCall(ctx context.Context, func (d *DAL) LoadAsyncCall(ctx context.Context, id int64) (*AsyncCall, error) { row, err := d.db.LoadAsyncCall(ctx, id) if err != nil { - return nil, dalerrs.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } origin, err := ParseAsyncOrigin(row.Origin) if err != nil { @@ -275,7 +276,7 @@ func (d *DAL) LoadAsyncCall(ctx context.Context, id int64) (*AsyncCall, error) { func (d *DAL) GetZombieAsyncCalls(ctx context.Context, limit int) ([]*AsyncCall, error) { rows, err := d.db.GetZombieAsyncCalls(ctx, int32(limit)) if err != nil { - return nil, dalerrs.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } var calls []*AsyncCall for _, row := range rows { diff --git a/backend/controller/dal/async_calls_test.go b/backend/controller/dal/async_calls_test.go index 0467d26433..3904fb2097 100644 --- a/backend/controller/dal/async_calls_test.go +++ b/backend/controller/dal/async_calls_test.go @@ -7,7 +7,7 @@ import ( "github.com/alecthomas/assert/v2" "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/log" @@ -21,7 +21,7 @@ func TestNoCallToAcquire(t *testing.T) { assert.NoError(t, err) _, _, err = dal.AcquireAsyncCall(ctx) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) assert.EqualError(t, err, "no pending async calls: not found") } diff --git a/backend/controller/dal/dal.go b/backend/controller/dal/dal.go index 8fbace64cf..7a35fd50fe 100644 --- a/backend/controller/dal/dal.go +++ b/backend/controller/dal/dal.go @@ -15,9 +15,10 @@ import ( sets "github.com/deckarep/golang-set/v2" "google.golang.org/protobuf/proto" + leasedal "github.com/TBD54566975/ftl/backend/controller/leases/dal" "github.com/TBD54566975/ftl/backend/controller/sql" "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" - "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/encryption" @@ -209,14 +210,16 @@ func WithReservation(ctx context.Context, reservation Reservation, fn func() err return reservation.Commit(ctx) } -func New(ctx context.Context, conn dal.Connection, encryptionBuilder encryption.Builder) (*DAL, error) { +func New(ctx context.Context, conn libdal.Connection, encryptionBuilder encryption.Builder) (*DAL, error) { var d *DAL d = &DAL{ - db: sql.New(conn), - Handle: dal.New(conn, func(h *dal.Handle[DAL]) *DAL { + leasedal: leasedal.New(conn), + db: sql.New(conn), + Handle: libdal.New(conn, func(h *libdal.Handle[DAL]) *DAL { return &DAL{ Handle: h, db: sql.New(h.Connection), + leasedal: leasedal.New(h.Connection), encryptor: d.encryptor, DeploymentChanges: d.DeploymentChanges, } @@ -235,9 +238,11 @@ func New(ctx context.Context, conn dal.Connection, encryptionBuilder encryption. } type DAL struct { - *dal.Handle[DAL] + *libdal.Handle[DAL] db sql.Querier + leasedal *leasedal.DAL + encryptor encryption.DataEncryptor // DeploymentChanges is a Topic that receives changes to the deployments table. @@ -247,7 +252,7 @@ type DAL struct { func (d *DAL) GetActiveControllers(ctx context.Context) ([]Controller, error) { controllers, err := d.db.GetActiveControllers(ctx) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return slices.Map(controllers, func(in sql.Controller) Controller { return Controller{ @@ -260,23 +265,23 @@ func (d *DAL) GetActiveControllers(ctx context.Context) ([]Controller, error) { func (d *DAL) GetStatus(ctx context.Context) (Status, error) { controllers, err := d.GetActiveControllers(ctx) if err != nil { - return Status{}, fmt.Errorf("could not get control planes: %w", dal.TranslatePGError(err)) + return Status{}, fmt.Errorf("could not get control planes: %w", libdal.TranslatePGError(err)) } runners, err := d.db.GetActiveRunners(ctx) if err != nil { - return Status{}, fmt.Errorf("could not get active runners: %w", dal.TranslatePGError(err)) + return Status{}, fmt.Errorf("could not get active runners: %w", libdal.TranslatePGError(err)) } deployments, err := d.db.GetActiveDeployments(ctx) if err != nil { - return Status{}, fmt.Errorf("could not get active deployments: %w", dal.TranslatePGError(err)) + return Status{}, fmt.Errorf("could not get active deployments: %w", libdal.TranslatePGError(err)) } ingressRoutes, err := d.db.GetActiveIngressRoutes(ctx) if err != nil { - return Status{}, fmt.Errorf("could not get ingress routes: %w", dal.TranslatePGError(err)) + return Status{}, fmt.Errorf("could not get ingress routes: %w", libdal.TranslatePGError(err)) } routes, err := d.db.GetRoutingTable(ctx, nil) if err != nil { - return Status{}, fmt.Errorf("could not get routing table: %w", dal.TranslatePGError(err)) + return Status{}, fmt.Errorf("could not get routing table: %w", libdal.TranslatePGError(err)) } statusDeployments, err := slices.MapErr(deployments, func(in sql.GetActiveDeploymentsRow) (Deployment, error) { labels := model.Labels{} @@ -349,7 +354,7 @@ func (d *DAL) GetRunnersForDeployment(ctx context.Context, deployment model.Depl runners := []Runner{} rows, err := d.db.GetRunnersForDeployment(ctx, deployment) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } for _, row := range rows { attrs := model.Labels{} @@ -370,14 +375,14 @@ func (d *DAL) GetRunnersForDeployment(ctx context.Context, deployment model.Depl func (d *DAL) UpsertModule(ctx context.Context, language, name string) (err error) { _, err = d.db.UpsertModule(ctx, language, name) - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } // GetMissingArtefacts returns the digests of the artefacts that are missing from the database. func (d *DAL) GetMissingArtefacts(ctx context.Context, digests []sha256.SHA256) ([]sha256.SHA256, error) { have, err := d.db.GetArtefactDigests(ctx, sha256esToBytes(digests)) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } haveStr := slices.Map(have, func(in sql.GetArtefactDigestsRow) sha256.SHA256 { return sha256.FromBytes(in.Digest) @@ -389,7 +394,7 @@ func (d *DAL) GetMissingArtefacts(ctx context.Context, digests []sha256.SHA256) func (d *DAL) CreateArtefact(ctx context.Context, content []byte) (digest sha256.SHA256, err error) { sha256digest := sha256.Sum(content) _, err = d.db.CreateArtefact(ctx, sha256digest[:], content) - return sha256digest, dal.TranslatePGError(err) + return sha256digest, libdal.TranslatePGError(err) } type IngressRoutingEntry struct { @@ -432,7 +437,7 @@ func (d *DAL) CreateDeployment(ctx context.Context, language string, moduleSchem // TODO(aat): "schema" containing language? _, err = tx.db.UpsertModule(ctx, language, moduleSchema.Name) if err != nil { - return model.DeploymentKey{}, fmt.Errorf("failed to upsert module: %w", dal.TranslatePGError(err)) + return model.DeploymentKey{}, fmt.Errorf("failed to upsert module: %w", libdal.TranslatePGError(err)) } // upsert topics @@ -448,7 +453,7 @@ func (d *DAL) CreateDeployment(ctx context.Context, language string, moduleSchem EventType: t.Event.String(), }) if err != nil { - return model.DeploymentKey{}, fmt.Errorf("could not insert topic: %w", dal.TranslatePGError(err)) + return model.DeploymentKey{}, fmt.Errorf("could not insert topic: %w", libdal.TranslatePGError(err)) } } @@ -457,7 +462,7 @@ func (d *DAL) CreateDeployment(ctx context.Context, language string, moduleSchem // Create the deployment err = tx.db.CreateDeployment(ctx, moduleSchema.Name, schemaBytes, deploymentKey) if err != nil { - return model.DeploymentKey{}, fmt.Errorf("failed to create deployment: %w", dal.TranslatePGError(err)) + return model.DeploymentKey{}, fmt.Errorf("failed to create deployment: %w", libdal.TranslatePGError(err)) } uploadedDigests := slices.Map(artefacts, func(in DeploymentArtefact) []byte { return in.Digest[:] }) @@ -480,7 +485,7 @@ func (d *DAL) CreateDeployment(ctx context.Context, language string, moduleSchem Path: artefact.Path, }) if err != nil { - return model.DeploymentKey{}, fmt.Errorf("failed to associate artefact with deployment: %w", dal.TranslatePGError(err)) + return model.DeploymentKey{}, fmt.Errorf("failed to associate artefact with deployment: %w", libdal.TranslatePGError(err)) } } @@ -493,7 +498,7 @@ func (d *DAL) CreateDeployment(ctx context.Context, language string, moduleSchem Verb: ingressRoute.Verb, }) if err != nil { - return model.DeploymentKey{}, fmt.Errorf("failed to create ingress route: %w", dal.TranslatePGError(err)) + return model.DeploymentKey{}, fmt.Errorf("failed to create ingress route: %w", libdal.TranslatePGError(err)) } } @@ -510,7 +515,7 @@ func (d *DAL) CreateDeployment(ctx context.Context, language string, moduleSchem NextExecution: job.NextExecution, }) if err != nil { - return model.DeploymentKey{}, fmt.Errorf("failed to create cron job: %w", dal.TranslatePGError(err)) + return model.DeploymentKey{}, fmt.Errorf("failed to create cron job: %w", libdal.TranslatePGError(err)) } } @@ -520,7 +525,7 @@ func (d *DAL) CreateDeployment(ctx context.Context, language string, moduleSchem func (d *DAL) GetDeployment(ctx context.Context, key model.DeploymentKey) (*model.Deployment, error) { deployment, err := d.db.GetDeployment(ctx, key) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return d.loadDeployment(ctx, deployment) } @@ -542,7 +547,7 @@ func (d *DAL) UpsertRunner(ctx context.Context, runner Runner) error { Labels: attrBytes, }) if err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } if runner.Deployment.Ok() && !deploymentID.Ok() { return fmt.Errorf("deployment %s not found", runner.Deployment) @@ -566,10 +571,10 @@ func (d *DAL) KillStaleControllers(ctx context.Context, age time.Duration) (int6 func (d *DAL) DeregisterRunner(ctx context.Context, key model.RunnerKey) error { count, err := d.db.DeregisterRunner(ctx, key) if err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } if count == 0 { - return dal.ErrNotFound + return libdal.ErrNotFound } return nil } @@ -586,23 +591,23 @@ func (d *DAL) ReserveRunnerForDeployment(ctx context.Context, deployment model.D tx, err := d.Begin(ctx) if err != nil { cancel() - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } runner, err := tx.db.ReserveRunner(ctx, time.Now().Add(reservationTimeout), deployment, jsonLabels) if err != nil { if rerr := tx.Rollback(context.Background()); rerr != nil { - err = errors.Join(err, dal.TranslatePGError(rerr)) + err = errors.Join(err, libdal.TranslatePGError(rerr)) } cancel() - if dal.IsNotFound(err) { - return nil, fmt.Errorf("no idle runners found matching labels %s: %w", jsonLabels, dal.ErrNotFound) + if libdal.IsNotFound(err) { + return nil, fmt.Errorf("no idle runners found matching labels %s: %w", jsonLabels, libdal.ErrNotFound) } - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } runnerLabels := model.Labels{} if err := json.Unmarshal(runner.Labels, &runnerLabels); err != nil { if rerr := tx.Rollback(context.Background()); rerr != nil { - err = errors.Join(err, dal.TranslatePGError(rerr)) + err = errors.Join(err, libdal.TranslatePGError(rerr)) } cancel() return nil, fmt.Errorf("failed to JSON decode labels for runner %d: %w", runner.ID, err) @@ -631,12 +636,12 @@ type postgresClaim struct { func (p *postgresClaim) Commit(ctx context.Context) error { defer p.cancel() - return dal.TranslatePGError(p.tx.Commit(ctx)) + return libdal.TranslatePGError(p.tx.Commit(ctx)) } func (p *postgresClaim) Rollback(ctx context.Context) error { defer p.cancel() - return dal.TranslatePGError(p.tx.Rollback(ctx)) + return libdal.TranslatePGError(p.tx.Rollback(ctx)) } func (p *postgresClaim) Runner() Runner { return p.runner } @@ -646,28 +651,28 @@ func (d *DAL) SetDeploymentReplicas(ctx context.Context, key model.DeploymentKey // Start the transaction tx, err := d.Begin(ctx) if err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } defer tx.CommitOrRollback(ctx, &err) deployment, err := tx.db.GetDeployment(ctx, key) if err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } err = tx.db.SetDeploymentDesiredReplicas(ctx, key, int32(minReplicas)) if err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } if minReplicas == 0 { err = tx.deploymentWillDeactivate(ctx, key) if err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } } else if deployment.MinReplicas == 0 { err = tx.deploymentWillActivate(ctx, key) if err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } } var payload encryption.EncryptedTimelineColumn @@ -683,7 +688,7 @@ func (d *DAL) SetDeploymentReplicas(ctx context.Context, key model.DeploymentKey Payload: payload, }) if err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } return nil @@ -698,19 +703,19 @@ func (d *DAL) ReplaceDeployment(ctx context.Context, newDeploymentKey model.Depl // Start the transaction tx, err := d.Begin(ctx) if err != nil { - return fmt.Errorf("replace deployment failed to begin transaction for %v: %w", newDeploymentKey, dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed to begin transaction for %v: %w", newDeploymentKey, libdal.TranslatePGError(err)) } defer tx.CommitOrRollback(ctx, &err) newDeployment, err := tx.db.GetDeployment(ctx, newDeploymentKey) if err != nil { - return fmt.Errorf("replace deployment failed to get deployment for %v: %w", newDeploymentKey, dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed to get deployment for %v: %w", newDeploymentKey, libdal.TranslatePGError(err)) } // must be called before deploymentWillDeactivate for the old deployment err = tx.deploymentWillActivate(ctx, newDeploymentKey) if err != nil { - return fmt.Errorf("replace deployment failed willActivate trigger for %v: %w", newDeploymentKey, dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed willActivate trigger for %v: %w", newDeploymentKey, libdal.TranslatePGError(err)) } // If there's an existing deployment, set its desired replicas to 0 @@ -722,25 +727,25 @@ func (d *DAL) ReplaceDeployment(ctx context.Context, newDeploymentKey model.Depl } err = tx.db.SetDeploymentDesiredReplicas(ctx, oldDeployment.Key, 0) if err != nil { - return fmt.Errorf("replace deployment failed to set old deployment replicas from %v to %v: %w", oldDeployment.Key, newDeploymentKey, dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed to set old deployment replicas from %v to %v: %w", oldDeployment.Key, newDeploymentKey, libdal.TranslatePGError(err)) } err = tx.db.SetDeploymentDesiredReplicas(ctx, newDeploymentKey, int32(minReplicas)) if err != nil { - return fmt.Errorf("replace deployment failed to set new deployment replicas from %v to %v: %w", oldDeployment.Key, newDeploymentKey, dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed to set new deployment replicas from %v to %v: %w", oldDeployment.Key, newDeploymentKey, libdal.TranslatePGError(err)) } err = d.deploymentWillDeactivate(ctx, oldDeployment.Key) if err != nil { - return fmt.Errorf("replace deployment failed willDeactivate trigger from %v to %v: %w", oldDeployment.Key, newDeploymentKey, dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed willDeactivate trigger from %v to %v: %w", oldDeployment.Key, newDeploymentKey, libdal.TranslatePGError(err)) } replacedDeploymentKey = optional.Some(oldDeployment.Key) - } else if !dal.IsNotFound(err) { + } else if !libdal.IsNotFound(err) { // any error other than not found - return fmt.Errorf("replace deployment failed to get existing deployment for %v: %w", newDeploymentKey, dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed to get existing deployment for %v: %w", newDeploymentKey, libdal.TranslatePGError(err)) } else { // Set the desired replicas for the new deployment err = tx.db.SetDeploymentDesiredReplicas(ctx, newDeploymentKey, int32(minReplicas)) if err != nil { - return fmt.Errorf("replace deployment failed to set replicas for %v: %w", newDeploymentKey, dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed to set replicas for %v: %w", newDeploymentKey, libdal.TranslatePGError(err)) } } @@ -760,7 +765,7 @@ func (d *DAL) ReplaceDeployment(ctx context.Context, newDeploymentKey model.Depl Payload: payload, }) if err != nil { - return fmt.Errorf("replace deployment failed to create event: %w", dal.TranslatePGError(err)) + return fmt.Errorf("replace deployment failed to create event: %w", libdal.TranslatePGError(err)) } return nil @@ -773,7 +778,7 @@ func (d *DAL) ReplaceDeployment(ctx context.Context, newDeploymentKey model.Depl func (d *DAL) deploymentWillActivate(ctx context.Context, key model.DeploymentKey) error { module, err := d.db.GetSchemaForDeployment(ctx, key) if err != nil { - return fmt.Errorf("could not get schema: %w", dal.TranslatePGError(err)) + return fmt.Errorf("could not get schema: %w", libdal.TranslatePGError(err)) } err = d.createSubscriptions(ctx, key, module) if err != nil { @@ -794,10 +799,10 @@ func (d *DAL) deploymentWillDeactivate(ctx context.Context, key model.Deployment func (d *DAL) GetDeploymentsNeedingReconciliation(ctx context.Context) ([]Reconciliation, error) { counts, err := d.db.GetDeploymentsNeedingReconciliation(ctx) if err != nil { - if dal.IsNotFound(err) { + if libdal.IsNotFound(err) { return nil, nil } - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return slices.Map(counts, func(t sql.GetDeploymentsNeedingReconciliationRow) Reconciliation { return Reconciliation{ @@ -814,10 +819,10 @@ func (d *DAL) GetDeploymentsNeedingReconciliation(ctx context.Context) ([]Reconc func (d *DAL) GetActiveDeployments(ctx context.Context) ([]Deployment, error) { rows, err := d.db.GetActiveDeployments(ctx) if err != nil { - if dal.IsNotFound(err) { + if libdal.IsNotFound(err) { return nil, nil } - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return slices.MapErr(rows, func(in sql.GetActiveDeploymentsRow) (Deployment, error) { return Deployment{ @@ -852,10 +857,10 @@ func (d *DAL) GetActiveSchema(ctx context.Context) (*schema.Schema, error) { func (d *DAL) GetDeploymentsWithMinReplicas(ctx context.Context) ([]Deployment, error) { rows, err := d.db.GetDeploymentsWithMinReplicas(ctx) if err != nil { - if dal.IsNotFound(err) { + if libdal.IsNotFound(err) { return nil, nil } - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return slices.MapErr(rows, func(in sql.GetDeploymentsWithMinReplicasRow) (Deployment, error) { return Deployment{ @@ -872,7 +877,7 @@ func (d *DAL) GetDeploymentsWithMinReplicas(ctx context.Context) ([]Deployment, func (d *DAL) GetActiveDeploymentSchemas(ctx context.Context) ([]*schema.Module, error) { rows, err := d.db.GetActiveDeploymentSchemas(ctx) if err != nil { - return nil, fmt.Errorf("could not get active deployments: %w", dal.TranslatePGError(err)) + return nil, fmt.Errorf("could not get active deployments: %w", libdal.TranslatePGError(err)) } return slices.MapErr(rows, func(in sql.GetActiveDeploymentSchemasRow) (*schema.Module, error) { return in.Schema, nil }) } @@ -894,7 +899,7 @@ type Process struct { func (d *DAL) GetProcessList(ctx context.Context) ([]Process, error) { rows, err := d.db.GetProcessList(ctx) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return slices.MapErr(rows, func(row sql.GetProcessListRow) (Process, error) { var runner optional.Option[ProcessRunner] @@ -939,10 +944,10 @@ func (d *DAL) GetIdleRunners(ctx context.Context, limit int, labels model.Labels return nil, fmt.Errorf("could not marshal labels: %w", err) } runners, err := d.db.GetIdleRunners(ctx, jsonb, int64(limit)) - if dal.IsNotFound(err) { + if libdal.IsNotFound(err) { return nil, nil } else if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return slices.MapErr(runners, func(row sql.Runner) (Runner, error) { rowLabels := model.Labels{} @@ -967,10 +972,10 @@ func (d *DAL) GetIdleRunners(ctx context.Context, limit int, labels model.Labels func (d *DAL) GetRoutingTable(ctx context.Context, modules []string) (map[string][]Route, error) { routes, err := d.db.GetRoutingTable(ctx, modules) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } if len(routes) == 0 { - return nil, fmt.Errorf("no routes found: %w", dal.ErrNotFound) + return nil, fmt.Errorf("no routes found: %w", libdal.ErrNotFound) } out := make(map[string][]Route, len(routes)) for _, route := range routes { @@ -990,7 +995,7 @@ func (d *DAL) GetRoutingTable(ctx context.Context, modules []string) (map[string func (d *DAL) GetRunnerState(ctx context.Context, runnerKey model.RunnerKey) (RunnerState, error) { state, err := d.db.GetRunnerState(ctx, runnerKey) if err != nil { - return "", dal.TranslatePGError(err) + return "", libdal.TranslatePGError(err) } return RunnerState(state), nil } @@ -998,14 +1003,14 @@ func (d *DAL) GetRunnerState(ctx context.Context, runnerKey model.RunnerKey) (Ru func (d *DAL) GetRunner(ctx context.Context, runnerKey model.RunnerKey) (Runner, error) { row, err := d.db.GetRunner(ctx, runnerKey) if err != nil { - return Runner{}, dal.TranslatePGError(err) + return Runner{}, libdal.TranslatePGError(err) } return runnerFromDB(row), nil } func (d *DAL) ExpireRunnerClaims(ctx context.Context) (int64, error) { count, err := d.db.ExpireRunnerReservations(ctx) - return count, dal.TranslatePGError(err) + return count, libdal.TranslatePGError(err) } func (d *DAL) InsertLogEvent(ctx context.Context, log *LogEvent) error { @@ -1025,7 +1030,7 @@ func (d *DAL) InsertLogEvent(ctx context.Context, log *LogEvent) error { if err != nil { return fmt.Errorf("failed to encrypt log payload: %w", err) } - return dal.TranslatePGError(d.db.InsertTimelineLogEvent(ctx, sql.InsertTimelineLogEventParams{ + return libdal.TranslatePGError(d.db.InsertTimelineLogEvent(ctx, sql.InsertTimelineLogEventParams{ DeploymentKey: log.DeploymentKey, RequestKey: requestKey, TimeStamp: log.Time, @@ -1043,7 +1048,7 @@ func (d *DAL) loadDeployment(ctx context.Context, deployment sql.GetDeploymentRo } artefacts, err := d.db.GetDeploymentArtefacts(ctx, deployment.Deployment.ID) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } out.Artefacts = slices.Map(artefacts, func(row sql.GetDeploymentArtefactsRow) *model.Artefact { return &model.Artefact{ @@ -1058,7 +1063,7 @@ func (d *DAL) loadDeployment(ctx context.Context, deployment sql.GetDeploymentRo func (d *DAL) CreateRequest(ctx context.Context, key model.RequestKey, addr string) error { if err := d.db.CreateRequest(ctx, sql.Origin(key.Payload.Origin), key, addr); err != nil { - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } return nil } @@ -1066,10 +1071,10 @@ func (d *DAL) CreateRequest(ctx context.Context, key model.RequestKey, addr stri func (d *DAL) GetIngressRoutes(ctx context.Context, method string) ([]IngressRoute, error) { routes, err := d.db.GetIngressRoutes(ctx, method) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } if len(routes) == 0 { - return nil, dal.ErrNotFound + return nil, libdal.ErrNotFound } return slices.Map(routes, func(row sql.GetIngressRoutesRow) IngressRoute { return IngressRoute{ @@ -1085,7 +1090,7 @@ func (d *DAL) GetIngressRoutes(ctx context.Context, method string) ([]IngressRou func (d *DAL) UpsertController(ctx context.Context, key model.ControllerKey, addr string) (int64, error) { id, err := d.db.UpsertController(ctx, key, addr) - return id, dal.TranslatePGError(err) + return id, libdal.TranslatePGError(err) } func (d *DAL) InsertCallEvent(ctx context.Context, call *CallEvent) error { @@ -1112,7 +1117,7 @@ func (d *DAL) InsertCallEvent(ctx context.Context, call *CallEvent) error { if err != nil { return fmt.Errorf("failed to encrypt call payload: %w", err) } - return dal.TranslatePGError(d.db.InsertTimelineCallEvent(ctx, sql.InsertTimelineCallEventParams{ + return libdal.TranslatePGError(d.db.InsertTimelineCallEvent(ctx, sql.InsertTimelineCallEventParams{ DeploymentKey: call.DeploymentKey, RequestKey: requestKey, ParentRequestKey: parentRequestKey, @@ -1127,13 +1132,13 @@ func (d *DAL) InsertCallEvent(ctx context.Context, call *CallEvent) error { func (d *DAL) DeleteOldEvents(ctx context.Context, eventType EventType, age time.Duration) (int64, error) { count, err := d.db.DeleteOldTimelineEvents(ctx, sqltypes.Duration(age), eventType) - return count, dal.TranslatePGError(err) + return count, libdal.TranslatePGError(err) } func (d *DAL) GetActiveRunners(ctx context.Context) ([]Runner, error) { rows, err := d.db.GetActiveRunners(ctx) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return slices.Map(rows, func(row sql.GetActiveRunnersRow) Runner { return runnerFromDB(sql.GetRunnerRow(row)) @@ -1175,7 +1180,7 @@ func (r *artefactReader) Close() error { return nil } func (r *artefactReader) Read(p []byte) (n int, err error) { content, err := r.db.GetArtefactContentRange(context.Background(), r.offset+1, int32(len(p)), r.id) if err != nil { - return 0, dal.TranslatePGError(err) + return 0, libdal.TranslatePGError(err) } copy(p, content) clen := len(content) diff --git a/backend/controller/dal/dal_test.go b/backend/controller/dal/dal_test.go index 669ebb6afe..a70b1d9638 100644 --- a/backend/controller/dal/dal_test.go +++ b/backend/controller/dal/dal_test.go @@ -14,7 +14,7 @@ import ( "golang.org/x/sync/errgroup" "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/encryption" @@ -90,7 +90,7 @@ func TestDAL(t *testing.T) { t.Run("GetMissingDeployment", func(t *testing.T) { _, err := dal.GetDeployment(ctx, model.NewDeploymentKey("invalid")) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) }) t.Run("GetMissingArtefacts", func(t *testing.T) { @@ -121,7 +121,7 @@ func TestDAL(t *testing.T) { State: RunnerStateIdle, }) assert.Error(t, err) - assert.IsError(t, err, dalerrs.ErrConflict) + assert.IsError(t, err, libdal.ErrConflict) }) t.Run("GetIdleRunnersForLanguage", func(t *testing.T) { @@ -170,7 +170,7 @@ func TestDAL(t *testing.T) { t.Run("ReserveRunnerForInvalidDeployment", func(t *testing.T) { _, err := dal.ReserveRunnerForDeployment(ctx, model.NewDeploymentKey("invalid"), time.Second, labels) assert.Error(t, err) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) assert.EqualError(t, err, "deployment: not found") }) @@ -194,7 +194,7 @@ func TestDAL(t *testing.T) { t.Run("ReserveRunnerForDeploymentFailsOnInvalidDeployment", func(t *testing.T) { _, err = dal.ReserveRunnerForDeployment(ctx, model.NewDeploymentKey("test"), time.Second, labels) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) }) t.Run("UpdateRunnerAssigned", func(t *testing.T) { @@ -321,7 +321,7 @@ func TestDAL(t *testing.T) { Deployment: optional.Some(model.NewDeploymentKey("test")), }) assert.Error(t, err) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) }) t.Run("ReleaseRunnerReservation", func(t *testing.T) { @@ -344,7 +344,7 @@ func TestDAL(t *testing.T) { t.Run("GetRoutingTable", func(t *testing.T) { _, err := dal.GetRoutingTable(ctx, []string{deployment.Module}) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) }) t.Run("DeregisterRunner", func(t *testing.T) { @@ -354,7 +354,7 @@ func TestDAL(t *testing.T) { t.Run("DeregisterRunnerFailsOnMissing", func(t *testing.T) { err = dal.DeregisterRunner(ctx, model.NewRunnerKey("localhost", "8080")) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) }) t.Run("VerifyDeploymentNotifications", func(t *testing.T) { diff --git a/backend/controller/dal/encryption.go b/backend/controller/dal/encryption.go index 844f0b5231..ad374ae3fa 100644 --- a/backend/controller/dal/encryption.go +++ b/backend/controller/dal/encryption.go @@ -7,7 +7,7 @@ import ( "github.com/alecthomas/types/optional" - "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/log" ) @@ -62,7 +62,7 @@ func (d *DAL) EnsureKey(ctx context.Context, generateKey func() ([]byte, error)) var key []byte row, err := tx.db.GetOnlyEncryptionKey(ctx) - if err != nil && dal.IsNotFound(err) { + if err != nil && libdal.IsNotFound(err) { logger.Debugf("No encryption key found, generating a new one") key, err = generateKey() if err != nil { @@ -94,7 +94,7 @@ func (d *DAL) verifyEncryptor(ctx context.Context, encryptor encryption.DataEncr row, err := tx.db.GetOnlyEncryptionKey(ctx) if err != nil { - if dal.IsNotFound(err) { + if libdal.IsNotFound(err) { // No encryption key found, probably using noop. return nil } diff --git a/backend/controller/dal/events.go b/backend/controller/dal/events.go index 3c26ade38b..eaf3d1c26f 100644 --- a/backend/controller/dal/events.go +++ b/backend/controller/dal/events.go @@ -11,7 +11,7 @@ import ( "github.com/alecthomas/types/optional" "github.com/TBD54566975/ftl/backend/controller/sql" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/log" "github.com/TBD54566975/ftl/internal/model" @@ -262,7 +262,7 @@ func (d *DAL) QueryTimeline(ctx context.Context, limit int, filters ...TimelineF } rows, err := d.Handle.Connection.QueryContext(ctx, deploymentQuery, deploymentArgs...) if err != nil { - return nil, dalerrs.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } defer rows.Close() // nolint:errcheck deploymentIDs := []int64{} @@ -318,7 +318,7 @@ func (d *DAL) QueryTimeline(ctx context.Context, limit int, filters ...TimelineF // Issue query. rows, err = d.Handle.Connection.QueryContext(ctx, q, args...) if err != nil { - return nil, fmt.Errorf("%s: %w", q, dalerrs.TranslatePGError(err)) + return nil, fmt.Errorf("%s: %w", q, libdal.TranslatePGError(err)) } defer rows.Close() diff --git a/backend/controller/dal/fsm.go b/backend/controller/dal/fsm.go index 8b694f8b48..55651481eb 100644 --- a/backend/controller/dal/fsm.go +++ b/backend/controller/dal/fsm.go @@ -13,7 +13,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/observability" "github.com/TBD54566975/ftl/backend/controller/sql" "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/encryption" ) @@ -56,7 +56,7 @@ func (d *DAL) StartFSMTransition(ctx context.Context, fsm schema.RefKey, instanc }) observability.AsyncCalls.Created(ctx, destinationState, retryParams.Catch, origin.String(), int64(retryParams.Count), err) if err != nil { - return fmt.Errorf("failed to create FSM async call: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("failed to create FSM async call: %w", libdal.TranslatePGError(err)) } queueDepth, err := d.db.AsyncCallQueueDepth(ctx) if err == nil { @@ -73,9 +73,9 @@ func (d *DAL) StartFSMTransition(ctx context.Context, fsm schema.RefKey, instanc AsyncCallID: asyncCallID, }) if err != nil { - err = dalerrs.TranslatePGError(err) - if errors.Is(err, dalerrs.ErrNotFound) { - return fmt.Errorf("transition already executing: %w", dalerrs.ErrConflict) + err = libdal.TranslatePGError(err) + if errors.Is(err, libdal.ErrNotFound) { + return fmt.Errorf("transition already executing: %w", libdal.ErrConflict) } return fmt.Errorf("failed to start FSM transition: %w", err) } @@ -91,7 +91,7 @@ func (d *DAL) FinishFSMTransition(ctx context.Context, instance *FSMInstance) (* _, err := d.db.FinishFSMTransition(ctx, instance.FSM, instance.Key) observability.FSM.TransitionCompleted(ctx, instance.FSM) if err != nil { - return nil, dalerrs.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return &FSMInstance{ Lease: instance.Lease, @@ -106,19 +106,19 @@ func (d *DAL) FinishFSMTransition(ctx context.Context, instance *FSMInstance) (* func (d *DAL) FailFSMInstance(ctx context.Context, fsm schema.RefKey, instanceKey string) error { _, err := d.db.FailFSMInstance(ctx, fsm, instanceKey) observability.FSM.InstanceCompleted(ctx, fsm) - return dalerrs.TranslatePGError(err) + return libdal.TranslatePGError(err) } func (d *DAL) SucceedFSMInstance(ctx context.Context, fsm schema.RefKey, instanceKey string) error { _, err := d.db.SucceedFSMInstance(ctx, fsm, instanceKey) observability.FSM.InstanceCompleted(ctx, fsm) - return dalerrs.TranslatePGError(err) + return libdal.TranslatePGError(err) } func (d *DAL) GetFSMStates(ctx context.Context, fsm schema.RefKey, instanceKey string) (currentState, destinationState optional.Option[schema.RefKey], err error) { instance, err := d.db.GetFSMInstance(ctx, fsm, instanceKey) if err != nil { - return optional.None[schema.RefKey](), optional.None[schema.RefKey](), dalerrs.TranslatePGError(err) + return optional.None[schema.RefKey](), optional.None[schema.RefKey](), libdal.TranslatePGError(err) } return instance.CurrentState, instance.DestinationState, nil } @@ -133,8 +133,8 @@ type NextFSMEvent struct { func (d *DAL) PopNextFSMEvent(ctx context.Context, fsm schema.RefKey, instanceKey string) (optional.Option[NextFSMEvent], error) { next, err := d.db.PopNextFSMEvent(ctx, fsm, instanceKey) if err != nil { - err = dalerrs.TranslatePGError(err) - if errors.Is(err, dalerrs.ErrNotFound) { + err = libdal.TranslatePGError(err) + if errors.Is(err, libdal.ErrNotFound) { return optional.None[NextFSMEvent](), nil } return optional.None[NextFSMEvent](), err @@ -157,11 +157,9 @@ func (d *DAL) SetNextFSMEvent(ctx context.Context, fsm schema.RefKey, instanceKe InstanceKey: instanceKey, Event: nextState, Request: encryptedRequest, - RequestType: sql.Type{ - Type: requestType, - }, + RequestType: sqltypes.Type{Type: requestType}, }) - return dalerrs.TranslatePGError(err) + return libdal.TranslatePGError(err) } type FSMStatus = sql.FsmStatus @@ -187,14 +185,14 @@ type FSMInstance struct { // // The lease must be released by the caller. func (d *DAL) AcquireFSMInstance(ctx context.Context, fsm schema.RefKey, instanceKey string) (*FSMInstance, error) { - lease, _, err := d.AcquireLease(ctx, leases.SystemKey("fsm_instance", fsm.String(), instanceKey), time.Second*5, optional.None[any]()) + lease, _, err := d.leasedal.AcquireLease(ctx, leases.SystemKey("fsm_instance", fsm.String(), instanceKey), time.Second*5, optional.None[any]()) if err != nil { return nil, fmt.Errorf("failed to acquire FSM lease: %w", err) } row, err := d.db.GetFSMInstance(ctx, fsm, instanceKey) if err != nil { - err = dalerrs.TranslatePGError(err) - if !errors.Is(err, dalerrs.ErrNotFound) { + err = libdal.TranslatePGError(err) + if !errors.Is(err, libdal.ErrNotFound) { return nil, err } row.Status = sql.FsmStatusRunning diff --git a/backend/controller/dal/fsm_test.go b/backend/controller/dal/fsm_test.go index a51bc58814..5af23510d5 100644 --- a/backend/controller/dal/fsm_test.go +++ b/backend/controller/dal/fsm_test.go @@ -8,8 +8,9 @@ import ( "github.com/alecthomas/assert/v2" "github.com/alecthomas/types/either" + leasedal "github.com/TBD54566975/ftl/backend/controller/leases/dal" "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/log" @@ -22,14 +23,14 @@ func TestSendFSMEvent(t *testing.T) { assert.NoError(t, err) _, _, err = dal.AcquireAsyncCall(ctx) - assert.IsError(t, err, dalerrs.ErrNotFound) + assert.IsError(t, err, libdal.ErrNotFound) ref := schema.RefKey{Module: "module", Name: "verb"} err = dal.StartFSMTransition(ctx, schema.RefKey{Module: "test", Name: "test"}, "invoiceID", ref, []byte(`{}`), false, schema.RetryParams{}) assert.NoError(t, err) err = dal.StartFSMTransition(ctx, schema.RefKey{Module: "test", Name: "test"}, "invoiceID", ref, []byte(`{}`), false, schema.RetryParams{}) - assert.IsError(t, err, dalerrs.ErrConflict) + assert.IsError(t, err, libdal.ErrConflict) assert.EqualError(t, err, "transition already executing: conflict") call, _, err := dal.AcquireAsyncCall(ctx) @@ -50,13 +51,13 @@ func TestSendFSMEvent(t *testing.T) { Request: []byte(`{}`), QueueDepth: 2, } - assert.Equal(t, expectedCall, call, assert.Exclude[*Lease](), assert.Exclude[time.Time]()) + assert.Equal(t, expectedCall, call, assert.Exclude[*leasedal.Lease](), assert.Exclude[time.Time]()) _, err = dal.CompleteAsyncCall(ctx, call, either.LeftOf[string]([]byte(`{}`)), func(tx *DAL, isFinalResult bool) error { return nil }) assert.NoError(t, err) actual, err := dal.LoadAsyncCall(ctx, call.ID) assert.NoError(t, err) - assert.Equal(t, call, actual, assert.Exclude[*Lease](), assert.Exclude[time.Time](), assert.Exclude[int64]()) + assert.Equal(t, call, actual, assert.Exclude[*leasedal.Lease](), assert.Exclude[time.Time](), assert.Exclude[int64]()) assert.Equal(t, call.ID, actual.ID) } diff --git a/backend/controller/dal/notify.go b/backend/controller/dal/notify.go index 2bcb150083..74716a3e28 100644 --- a/backend/controller/dal/notify.go +++ b/backend/controller/dal/notify.go @@ -14,7 +14,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/jpillora/backoff" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/internal/log" "github.com/TBD54566975/ftl/internal/model" ) @@ -191,7 +191,7 @@ func (d *DAL) publishNotification(ctx context.Context, notification event, logge deployment, err := decodeNotification(notification, func(key model.DeploymentKey) (Deployment, optional.Option[model.DeploymentKey], error) { row, err := d.db.GetDeployment(ctx, key) if err != nil { - return Deployment{}, optional.None[model.DeploymentKey](), dalerrs.TranslatePGError(err) + return Deployment{}, optional.None[model.DeploymentKey](), libdal.TranslatePGError(err) } return Deployment{ CreatedAt: row.Deployment.CreatedAt, diff --git a/backend/controller/dal/pubsub.go b/backend/controller/dal/pubsub.go index bee0d36528..ad00636f9e 100644 --- a/backend/controller/dal/pubsub.go +++ b/backend/controller/dal/pubsub.go @@ -11,7 +11,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/observability" "github.com/TBD54566975/ftl/backend/controller/sql" "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/log" @@ -55,7 +55,7 @@ func (d *DAL) PublishEventForTopic(ctx context.Context, module, topic, caller st }) observability.PubSub.Published(ctx, module, topic, caller, err) if err != nil { - return dalerrs.TranslatePGError(err) + return libdal.TranslatePGError(err) } return nil } @@ -63,7 +63,7 @@ func (d *DAL) PublishEventForTopic(ctx context.Context, module, topic, caller st func (d *DAL) GetSubscriptionsNeedingUpdate(ctx context.Context) ([]model.Subscription, error) { rows, err := d.db.GetSubscriptionsNeedingUpdate(ctx) if err != nil { - return nil, dalerrs.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return slices.Map(rows, func(row sql.GetSubscriptionsNeedingUpdateRow) model.Subscription { return model.Subscription{ @@ -88,7 +88,7 @@ func (d *DAL) ProgressSubscriptions(ctx context.Context, eventConsumptionDelay t // also gets a lock on the subscription, and skips any subscriptions locked by others subs, err := tx.db.GetSubscriptionsNeedingUpdate(ctx) if err != nil { - return 0, fmt.Errorf("could not get subscriptions to progress: %w", dalerrs.TranslatePGError(err)) + return 0, fmt.Errorf("could not get subscriptions to progress: %w", libdal.TranslatePGError(err)) } successful := 0 @@ -96,12 +96,12 @@ func (d *DAL) ProgressSubscriptions(ctx context.Context, eventConsumptionDelay t nextCursor, err := tx.db.GetNextEventForSubscription(ctx, sqltypes.Duration(eventConsumptionDelay), subscription.Topic, subscription.Cursor) if err != nil { observability.PubSub.PropagationFailed(ctx, "GetNextEventForSubscription", subscription.Topic.Payload, nextCursor.Caller, subscriptionRef(subscription), optional.None[schema.RefKey]()) - return 0, fmt.Errorf("failed to get next cursor: %w", dalerrs.TranslatePGError(err)) + return 0, fmt.Errorf("failed to get next cursor: %w", libdal.TranslatePGError(err)) } nextCursorKey, ok := nextCursor.Event.Get() if !ok { observability.PubSub.PropagationFailed(ctx, "GetNextEventForSubscription-->Event.Get", subscription.Topic.Payload, nextCursor.Caller, subscriptionRef(subscription), optional.None[schema.RefKey]()) - return 0, fmt.Errorf("could not find event to progress subscription: %w", dalerrs.TranslatePGError(err)) + return 0, fmt.Errorf("could not find event to progress subscription: %w", libdal.TranslatePGError(err)) } if !nextCursor.Ready { logger.Tracef("Skipping subscription %s because event is too new", subscription.Key) @@ -117,7 +117,7 @@ func (d *DAL) ProgressSubscriptions(ctx context.Context, eventConsumptionDelay t err = tx.db.BeginConsumingTopicEvent(ctx, subscription.Key, nextCursorKey) if err != nil { observability.PubSub.PropagationFailed(ctx, "BeginConsumingTopicEvent", subscription.Topic.Payload, nextCursor.Caller, subscriptionRef(subscription), optional.Some(subscriber.Sink)) - return 0, fmt.Errorf("failed to progress subscription: %w", dalerrs.TranslatePGError(err)) + return 0, fmt.Errorf("failed to progress subscription: %w", libdal.TranslatePGError(err)) } origin := AsyncOriginPubSub{ @@ -142,7 +142,7 @@ func (d *DAL) ProgressSubscriptions(ctx context.Context, eventConsumptionDelay t observability.AsyncCalls.Created(ctx, subscriber.Sink, subscriber.CatchVerb, origin.String(), int64(subscriber.RetryAttempts), err) if err != nil { observability.PubSub.PropagationFailed(ctx, "CreateAsyncCall", subscription.Topic.Payload, nextCursor.Caller, subscriptionRef(subscription), optional.Some(subscriber.Sink)) - return 0, fmt.Errorf("failed to schedule async task for subscription: %w", dalerrs.TranslatePGError(err)) + return 0, fmt.Errorf("failed to schedule async task for subscription: %w", libdal.TranslatePGError(err)) } observability.PubSub.SinkCalled(ctx, subscription.Topic.Payload, nextCursor.Caller, subscriptionRef(subscription), subscriber.Sink) @@ -170,7 +170,7 @@ func subscriptionRef(subscription sql.GetSubscriptionsNeedingUpdateRow) schema.R func (d *DAL) CompleteEventForSubscription(ctx context.Context, module, name string) error { err := d.db.CompleteEventForSubscription(ctx, name, module) if err != nil { - return fmt.Errorf("failed to complete event for subscription: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("failed to complete event for subscription: %w", libdal.TranslatePGError(err)) } return nil } @@ -185,15 +185,15 @@ func (d *DAL) ResetSubscription(ctx context.Context, module, name string) (err e subscription, err := tx.db.GetSubscription(ctx, name, module) if err != nil { - if dalerrs.IsNotFound(err) { + if libdal.IsNotFound(err) { return fmt.Errorf("subscription %s.%s not found", module, name) } - return fmt.Errorf("could not fetch subscription: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("could not fetch subscription: %w", libdal.TranslatePGError(err)) } topic, err := tx.db.GetTopic(ctx, subscription.TopicID) if err != nil { - return fmt.Errorf("could not fetch topic: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("could not fetch topic: %w", libdal.TranslatePGError(err)) } headEventID, ok := topic.Head.Get() @@ -203,12 +203,12 @@ func (d *DAL) ResetSubscription(ctx context.Context, module, name string) (err e headEvent, err := tx.db.GetTopicEvent(ctx, headEventID) if err != nil { - return fmt.Errorf("could not fetch topic head: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("could not fetch topic head: %w", libdal.TranslatePGError(err)) } err = tx.db.SetSubscriptionCursor(ctx, subscription.Key, headEvent.Key) if err != nil { - return fmt.Errorf("failed to reset subscription: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("failed to reset subscription: %w", libdal.TranslatePGError(err)) } return nil @@ -241,7 +241,7 @@ func (d *DAL) createSubscriptions(ctx context.Context, key model.DeploymentKey, Name: s.Name, }) if err != nil { - return fmt.Errorf("could not insert subscription: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("could not insert subscription: %w", libdal.TranslatePGError(err)) } if result.Inserted { logger.Debugf("Inserted subscription %s for %s", subscriptionKey, key) @@ -308,7 +308,7 @@ func (d *DAL) createSubscribers(ctx context.Context, key model.DeploymentKey, mo CatchVerb: retryParams.Catch, }) if err != nil { - return fmt.Errorf("could not insert subscriber: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("could not insert subscriber: %w", libdal.TranslatePGError(err)) } logger.Debugf("Inserted subscriber %s for %s", subscriberKey, key) } @@ -321,7 +321,7 @@ func (d *DAL) removeSubscriptionsAndSubscribers(ctx context.Context, key model.D subscribers, err := d.db.DeleteSubscribers(ctx, key) if err != nil { - return fmt.Errorf("could not delete old subscribers: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("could not delete old subscribers: %w", libdal.TranslatePGError(err)) } if len(subscribers) > 0 { logger.Debugf("Deleted subscribers for %s: %s", key, strings.Join(slices.Map(subscribers, func(key model.SubscriberKey) string { return key.String() }), ", ")) @@ -329,7 +329,7 @@ func (d *DAL) removeSubscriptionsAndSubscribers(ctx context.Context, key model.D subscriptions, err := d.db.DeleteSubscriptions(ctx, key) if err != nil { - return fmt.Errorf("could not delete old subscriptions: %w", dalerrs.TranslatePGError(err)) + return fmt.Errorf("could not delete old subscriptions: %w", libdal.TranslatePGError(err)) } if len(subscriptions) > 0 { logger.Debugf("Deleted subscriptions for %s: %s", key, strings.Join(slices.Map(subscriptions, func(key model.SubscriptionKey) string { return key.String() }), ", ")) diff --git a/backend/controller/dal/testdata/go/fsm/go.mod b/backend/controller/dal/testdata/go/fsm/go.mod index 6b2e9b7d6f..dd22487a02 100644 --- a/backend/controller/dal/testdata/go/fsm/go.mod +++ b/backend/controller/dal/testdata/go/fsm/go.mod @@ -19,7 +19,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -43,7 +42,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/backend/controller/dal/testdata/go/fsm/go.sum b/backend/controller/dal/testdata/go/fsm/go.sum index 98987bd625..13edf2824d 100644 --- a/backend/controller/dal/testdata/go/fsm/go.sum +++ b/backend/controller/dal/testdata/go/fsm/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/backend/controller/dal/testdata/go/fsmnext/go.mod b/backend/controller/dal/testdata/go/fsmnext/go.mod index 7ee891c68b..55a65917eb 100644 --- a/backend/controller/dal/testdata/go/fsmnext/go.mod +++ b/backend/controller/dal/testdata/go/fsmnext/go.mod @@ -19,7 +19,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -43,7 +42,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/backend/controller/dal/testdata/go/fsmnext/go.sum b/backend/controller/dal/testdata/go/fsmnext/go.sum index 98987bd625..13edf2824d 100644 --- a/backend/controller/dal/testdata/go/fsmnext/go.sum +++ b/backend/controller/dal/testdata/go/fsmnext/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/backend/controller/ingress/handler.go b/backend/controller/ingress/handler.go index 2bcc3c433b..d9dc2cc332 100644 --- a/backend/controller/ingress/handler.go +++ b/backend/controller/ingress/handler.go @@ -13,7 +13,7 @@ import ( "github.com/TBD54566975/ftl/backend/controller/dal" "github.com/TBD54566975/ftl/backend/controller/observability" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema" "github.com/TBD54566975/ftl/backend/schema" @@ -35,7 +35,7 @@ func Handle( logger.Debugf("Start ingress request") route, err := GetIngressRoute(routes, r.Method, r.URL.Path) if err != nil { - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { http.NotFound(w, r) observability.Ingress.Request(r.Context(), r.Method, r.URL.Path, optional.None[*schemapb.Ref](), startTime, optional.Some("route not found")) return diff --git a/backend/controller/ingress/ingress.go b/backend/controller/ingress/ingress.go index 4d345bf804..2cd77408ff 100644 --- a/backend/controller/ingress/ingress.go +++ b/backend/controller/ingress/ingress.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/TBD54566975/ftl/backend/controller/dal" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/slices" ) @@ -18,7 +18,7 @@ func GetIngressRoute(routes []dal.IngressRoute, method string, path string) (*da }) if len(matchedRoutes) == 0 { - return nil, dalerrs.ErrNotFound + return nil, libdal.ErrNotFound } // TODO: add load balancing at some point diff --git a/backend/controller/leader/leader.go b/backend/controller/leader/leader.go index 79c4081a2b..895244da68 100644 --- a/backend/controller/leader/leader.go +++ b/backend/controller/leader/leader.go @@ -24,7 +24,7 @@ import ( "github.com/alecthomas/types/optional" "github.com/TBD54566975/ftl/backend/controller/leases" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/internal/log" ) @@ -177,7 +177,7 @@ func (c *Coordinator[P]) createFollower() (out P, err error) { var urlString string expiry, err := c.leaser.GetLeaseInfo(c.ctx, c.key, &urlString) if err != nil { - if errors.Is(err, dalerrs.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { return out, fmt.Errorf("could not acquire or find lease for %s", c.key) } return out, fmt.Errorf("could not get lease for %s: %w", c.key, err) diff --git a/backend/controller/dal/lease.go b/backend/controller/leases/dal/dal.go similarity index 79% rename from backend/controller/dal/lease.go rename to backend/controller/leases/dal/dal.go index 23634173a1..fc2cb7d3d7 100644 --- a/backend/controller/dal/lease.go +++ b/backend/controller/leases/dal/dal.go @@ -12,12 +12,29 @@ import ( "github.com/sqlc-dev/pqtype" "github.com/TBD54566975/ftl/backend/controller/leases" - "github.com/TBD54566975/ftl/backend/controller/sql" + "github.com/TBD54566975/ftl/backend/controller/leases/dal/internal/sql" "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/internal/log" ) +type DAL struct { + *libdal.Handle[DAL] + db sql.Querier +} + +func New(conn libdal.Connection) *DAL { + return &DAL{ + Handle: libdal.New(conn, func(h *libdal.Handle[DAL]) *DAL { + return &DAL{ + Handle: h, + db: sql.New(h.Connection), + } + }), + db: sql.New(conn), + } +} + var _ leases.Leaser = (*DAL)(nil) // Lease represents a lease that is held by a controller. @@ -50,8 +67,8 @@ func (l *Lease) renew(ctx context.Context, cancelCtx context.CancelFunc) { cancel() if err != nil { - err = dalerrs.TranslatePGError(err) - if errors.Is(err, dalerrs.ErrNotFound) { + err = libdal.TranslatePGError(err) + if errors.Is(err, libdal.ErrNotFound) { logger.Warnf("Lease expired") } else { logger.Errorf(err, "Failed to renew lease %s", l.key) @@ -67,7 +84,7 @@ func (l *Lease) renew(ctx context.Context, cancelCtx context.CancelFunc) { } logger.Debugf("Releasing lease") _, err := l.db.ReleaseLease(ctx, l.idempotencyKey, l.key) - l.errch <- dalerrs.TranslatePGError(err) + l.errch <- libdal.TranslatePGError(err) cancelCtx() return } @@ -81,7 +98,7 @@ func (l *Lease) Release() error { // AcquireLease acquires a lease for the given key. // -// Will return leases.ErrConflict (not dalerrs.ErrConflict) if the lease is already held by another controller. +// Will return leases.ErrConflict (not libdal.ErrConflict) if the lease is already held by another controller. // // The returned context will be cancelled when the lease fails to renew. func (d *DAL) AcquireLease(ctx context.Context, key leases.Key, ttl time.Duration, metadata optional.Option[any]) (leases.Lease, context.Context, error) { @@ -98,17 +115,18 @@ func (d *DAL) AcquireLease(ctx context.Context, key leases.Key, ttl time.Duratio } idempotencyKey, err := d.db.NewLease(ctx, key, sqltypes.Duration(ttl), pqtype.NullRawMessage{RawMessage: metadataBytes, Valid: true}) if err != nil { - err = dalerrs.TranslatePGError(err) - if errors.Is(err, dalerrs.ErrConflict) { + err = libdal.TranslatePGError(err) + if errors.Is(err, libdal.ErrConflict) { return nil, nil, leases.ErrConflict } return nil, nil, err } - leaseCtx, lease := d.newLease(ctx, key, idempotencyKey, ttl) + leaseCtx, lease := d.NewLease(ctx, key, idempotencyKey, ttl) return leaseCtx, lease, nil } -func (d *DAL) newLease(ctx context.Context, key leases.Key, idempotencyKey uuid.UUID, ttl time.Duration) (*Lease, context.Context) { +// NewLease creates a new lease for the given key. +func (d *DAL) NewLease(ctx context.Context, key leases.Key, idempotencyKey uuid.UUID, ttl time.Duration) (*Lease, context.Context) { ctx, cancelCtx := context.WithCancel(ctx) lease := &Lease{ idempotencyKey: idempotencyKey, @@ -128,7 +146,7 @@ func (d *DAL) newLease(ctx context.Context, key leases.Key, idempotencyKey uuid. func (d *DAL) GetLeaseInfo(ctx context.Context, key leases.Key, metadata any) (expiry time.Time, err error) { l, err := d.db.GetLeaseInfo(ctx, key) if err != nil { - return expiry, dalerrs.TranslatePGError(err) + return expiry, libdal.TranslatePGError(err) } if l.Metadata.Valid { if err := json.Unmarshal(l.Metadata.RawMessage, metadata); err != nil { @@ -145,5 +163,5 @@ func (d *DAL) ExpireLeases(ctx context.Context) error { if count > 0 { log.FromContext(ctx).Warnf("Expired %d leases", count) } - return dalerrs.TranslatePGError(err) + return libdal.TranslatePGError(err) } diff --git a/backend/controller/dal/lease_test.go b/backend/controller/leases/dal/dal_test.go similarity index 83% rename from backend/controller/dal/lease_test.go rename to backend/controller/leases/dal/dal_test.go index 182dc8275b..5d345664cf 100644 --- a/backend/controller/dal/lease_test.go +++ b/backend/controller/leases/dal/dal_test.go @@ -12,18 +12,17 @@ import ( "github.com/TBD54566975/ftl/backend/controller/leases" "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" - "github.com/TBD54566975/ftl/backend/dal" - "github.com/TBD54566975/ftl/internal/encryption" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/internal/log" ) -func leaseExists(t *testing.T, conn dal.Connection, idempotencyKey uuid.UUID, key leases.Key) bool { +func leaseExists(t *testing.T, conn libdal.Connection, idempotencyKey uuid.UUID, key leases.Key) bool { t.Helper() var count int - err := dal.TranslatePGError(conn. + err := libdal.TranslatePGError(conn. QueryRowContext(context.Background(), "SELECT COUNT(*) FROM leases WHERE idempotency_key = $1 AND key = $2", idempotencyKey, key). Scan(&count)) - if errors.Is(err, dal.ErrNotFound) { + if errors.Is(err, libdal.ErrNotFound) { return false } assert.NoError(t, err) @@ -36,11 +35,10 @@ func TestLease(t *testing.T) { } ctx := log.ContextWithNewDefaultLogger(context.Background()) conn := sqltest.OpenForTesting(ctx, t) - dal, err := New(ctx, conn, encryption.NewBuilder()) - assert.NoError(t, err) + dal := New(conn) // TTL is too short, expect an error - _, _, err = dal.AcquireLease(ctx, leases.SystemKey("test"), time.Second*1, optional.None[any]()) + _, _, err := dal.AcquireLease(ctx, leases.SystemKey("test"), time.Second*1, optional.None[any]()) assert.Error(t, err) leasei, leaseCtx, err := dal.AcquireLease(ctx, leases.SystemKey("test"), time.Second*5, optional.None[any]()) @@ -71,8 +69,7 @@ func TestExpireLeases(t *testing.T) { } ctx := log.ContextWithNewDefaultLogger(context.Background()) conn := sqltest.OpenForTesting(ctx, t) - dal, err := New(ctx, conn, encryption.NewBuilder()) - assert.NoError(t, err) + dal := New(conn) leasei, _, err := dal.AcquireLease(ctx, leases.SystemKey("test"), time.Second*5, optional.None[any]()) assert.NoError(t, err) diff --git a/backend/controller/leases/dal/internal/sql/db.go b/backend/controller/leases/dal/internal/sql/db.go new file mode 100644 index 0000000000..0e0973111c --- /dev/null +++ b/backend/controller/leases/dal/internal/sql/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.27.0 + +package sql + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/backend/controller/leases/dal/internal/sql/models.go b/backend/controller/leases/dal/internal/sql/models.go new file mode 100644 index 0000000000..49d53f0d84 --- /dev/null +++ b/backend/controller/leases/dal/internal/sql/models.go @@ -0,0 +1,538 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.27.0 + +package sql + +import ( + "database/sql/driver" + "encoding/json" + "fmt" + "time" + + "github.com/TBD54566975/ftl/backend/controller/leases" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" + "github.com/TBD54566975/ftl/backend/schema" + "github.com/TBD54566975/ftl/internal/encryption" + "github.com/TBD54566975/ftl/internal/model" + "github.com/alecthomas/types/optional" + "github.com/google/uuid" + "github.com/sqlc-dev/pqtype" +) + +type AsyncCallState string + +const ( + AsyncCallStatePending AsyncCallState = "pending" + AsyncCallStateExecuting AsyncCallState = "executing" + AsyncCallStateSuccess AsyncCallState = "success" + AsyncCallStateError AsyncCallState = "error" +) + +func (e *AsyncCallState) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = AsyncCallState(s) + case string: + *e = AsyncCallState(s) + default: + return fmt.Errorf("unsupported scan type for AsyncCallState: %T", src) + } + return nil +} + +type NullAsyncCallState struct { + AsyncCallState AsyncCallState + Valid bool // Valid is true if AsyncCallState is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullAsyncCallState) Scan(value interface{}) error { + if value == nil { + ns.AsyncCallState, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.AsyncCallState.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullAsyncCallState) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.AsyncCallState), nil +} + +type ControllerState string + +const ( + ControllerStateLive ControllerState = "live" + ControllerStateDead ControllerState = "dead" +) + +func (e *ControllerState) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = ControllerState(s) + case string: + *e = ControllerState(s) + default: + return fmt.Errorf("unsupported scan type for ControllerState: %T", src) + } + return nil +} + +type NullControllerState struct { + ControllerState ControllerState + Valid bool // Valid is true if ControllerState is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullControllerState) Scan(value interface{}) error { + if value == nil { + ns.ControllerState, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.ControllerState.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullControllerState) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.ControllerState), nil +} + +type EventType string + +const ( + EventTypeCall EventType = "call" + EventTypeLog EventType = "log" + EventTypeDeploymentCreated EventType = "deployment_created" + EventTypeDeploymentUpdated EventType = "deployment_updated" +) + +func (e *EventType) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = EventType(s) + case string: + *e = EventType(s) + default: + return fmt.Errorf("unsupported scan type for EventType: %T", src) + } + return nil +} + +type NullEventType struct { + EventType EventType + Valid bool // Valid is true if EventType is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullEventType) Scan(value interface{}) error { + if value == nil { + ns.EventType, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.EventType.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullEventType) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.EventType), nil +} + +type FsmStatus string + +const ( + FsmStatusRunning FsmStatus = "running" + FsmStatusCompleted FsmStatus = "completed" + FsmStatusFailed FsmStatus = "failed" +) + +func (e *FsmStatus) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = FsmStatus(s) + case string: + *e = FsmStatus(s) + default: + return fmt.Errorf("unsupported scan type for FsmStatus: %T", src) + } + return nil +} + +type NullFsmStatus struct { + FsmStatus FsmStatus + Valid bool // Valid is true if FsmStatus is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullFsmStatus) Scan(value interface{}) error { + if value == nil { + ns.FsmStatus, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.FsmStatus.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullFsmStatus) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.FsmStatus), nil +} + +type Origin string + +const ( + OriginIngress Origin = "ingress" + OriginCron Origin = "cron" + OriginPubsub Origin = "pubsub" +) + +func (e *Origin) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = Origin(s) + case string: + *e = Origin(s) + default: + return fmt.Errorf("unsupported scan type for Origin: %T", src) + } + return nil +} + +type NullOrigin struct { + Origin Origin + Valid bool // Valid is true if Origin is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullOrigin) Scan(value interface{}) error { + if value == nil { + ns.Origin, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.Origin.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullOrigin) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.Origin), nil +} + +type RunnerState string + +const ( + RunnerStateIdle RunnerState = "idle" + RunnerStateReserved RunnerState = "reserved" + RunnerStateAssigned RunnerState = "assigned" + RunnerStateDead RunnerState = "dead" +) + +func (e *RunnerState) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = RunnerState(s) + case string: + *e = RunnerState(s) + default: + return fmt.Errorf("unsupported scan type for RunnerState: %T", src) + } + return nil +} + +type NullRunnerState struct { + RunnerState RunnerState + Valid bool // Valid is true if RunnerState is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullRunnerState) Scan(value interface{}) error { + if value == nil { + ns.RunnerState, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.RunnerState.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullRunnerState) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.RunnerState), nil +} + +type TopicSubscriptionState string + +const ( + TopicSubscriptionStateIdle TopicSubscriptionState = "idle" + TopicSubscriptionStateExecuting TopicSubscriptionState = "executing" +) + +func (e *TopicSubscriptionState) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = TopicSubscriptionState(s) + case string: + *e = TopicSubscriptionState(s) + default: + return fmt.Errorf("unsupported scan type for TopicSubscriptionState: %T", src) + } + return nil +} + +type NullTopicSubscriptionState struct { + TopicSubscriptionState TopicSubscriptionState + Valid bool // Valid is true if TopicSubscriptionState is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullTopicSubscriptionState) Scan(value interface{}) error { + if value == nil { + ns.TopicSubscriptionState, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.TopicSubscriptionState.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullTopicSubscriptionState) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.TopicSubscriptionState), nil +} + +type Artefact struct { + ID int64 + CreatedAt time.Time + Digest []byte + Content []byte +} + +type AsyncCall struct { + ID int64 + CreatedAt time.Time + LeaseID optional.Option[int64] + Verb schema.RefKey + State AsyncCallState + Origin string + ScheduledAt time.Time + Request encryption.EncryptedAsyncColumn + Response encryption.OptionalEncryptedAsyncColumn + Error optional.Option[string] + RemainingAttempts int32 + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration + CatchVerb optional.Option[schema.RefKey] + Catching bool + ParentRequestKey optional.Option[string] + TraceContext pqtype.NullRawMessage +} + +type Controller struct { + ID int64 + Key model.ControllerKey + Created time.Time + LastSeen time.Time + State ControllerState + Endpoint string +} + +type CronJob struct { + ID int64 + Key model.CronJobKey + DeploymentID int64 + Verb string + Schedule string + StartTime time.Time + NextExecution time.Time + ModuleName string + LastExecution optional.Option[time.Time] + LastAsyncCallID optional.Option[int64] +} + +type Deployment struct { + ID int64 + CreatedAt time.Time + ModuleID int64 + Key model.DeploymentKey + Schema *schema.Module + Labels json.RawMessage + MinReplicas int32 +} + +type DeploymentArtefact struct { + ArtefactID int64 + DeploymentID int64 + CreatedAt time.Time + Executable bool + Path string +} + +type EncryptionKey struct { + ID int64 + Key []byte + CreatedAt time.Time + VerifyTimeline encryption.OptionalEncryptedTimelineColumn + VerifyAsync encryption.OptionalEncryptedAsyncColumn +} + +type FsmInstance struct { + ID int64 + CreatedAt time.Time + Fsm schema.RefKey + Key string + Status FsmStatus + CurrentState optional.Option[schema.RefKey] + DestinationState optional.Option[schema.RefKey] + AsyncCallID optional.Option[int64] + UpdatedAt time.Time +} + +type FsmNextEvent struct { + ID int64 + CreatedAt time.Time + FsmInstanceID int64 + NextState schema.RefKey + Request []byte + RequestType sqltypes.Type +} + +type IngressRoute struct { + Method string + Path string + DeploymentID int64 + Module string + Verb string +} + +type Lease struct { + ID int64 + IdempotencyKey uuid.UUID + Key leases.Key + CreatedAt time.Time + ExpiresAt time.Time + Metadata pqtype.NullRawMessage +} + +type Module struct { + ID int64 + Language string + Name string +} + +type ModuleConfiguration struct { + ID int64 + CreatedAt time.Time + Module optional.Option[string] + Name string + Value json.RawMessage +} + +type ModuleSecret struct { + ID int64 + CreatedAt time.Time + Module optional.Option[string] + Name string + Url string +} + +type Request struct { + ID int64 + Origin Origin + Key model.RequestKey + SourceAddr string +} + +type Runner struct { + ID int64 + Key model.RunnerKey + Created time.Time + LastSeen time.Time + ReservationTimeout optional.Option[time.Time] + State RunnerState + Endpoint string + ModuleName optional.Option[string] + DeploymentID optional.Option[int64] + Labels json.RawMessage +} + +type Timeline struct { + ID int64 + TimeStamp time.Time + DeploymentID int64 + RequestID optional.Option[int64] + Type EventType + CustomKey1 optional.Option[string] + CustomKey2 optional.Option[string] + CustomKey3 optional.Option[string] + CustomKey4 optional.Option[string] + Payload encryption.EncryptedTimelineColumn + ParentRequestID optional.Option[string] +} + +type Topic struct { + ID int64 + Key model.TopicKey + CreatedAt time.Time + ModuleID int64 + Name string + Type string + Head optional.Option[int64] +} + +type TopicEvent struct { + ID int64 + CreatedAt time.Time + Key model.TopicEventKey + TopicID int64 + Payload []byte + Caller optional.Option[string] + RequestKey optional.Option[string] + TraceContext pqtype.NullRawMessage +} + +type TopicSubscriber struct { + ID int64 + Key model.SubscriberKey + CreatedAt time.Time + TopicSubscriptionsID int64 + DeploymentID int64 + Sink schema.RefKey + RetryAttempts int32 + Backoff sqltypes.Duration + MaxBackoff sqltypes.Duration + CatchVerb optional.Option[schema.RefKey] +} + +type TopicSubscription struct { + ID int64 + Key model.SubscriptionKey + CreatedAt time.Time + TopicID int64 + ModuleID int64 + DeploymentID int64 + Name string + Cursor optional.Option[int64] + State TopicSubscriptionState +} diff --git a/backend/controller/leases/dal/internal/sql/querier.go b/backend/controller/leases/dal/internal/sql/querier.go new file mode 100644 index 0000000000..04b6ba54cc --- /dev/null +++ b/backend/controller/leases/dal/internal/sql/querier.go @@ -0,0 +1,24 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.27.0 + +package sql + +import ( + "context" + + "github.com/TBD54566975/ftl/backend/controller/leases" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" + "github.com/google/uuid" + "github.com/sqlc-dev/pqtype" +) + +type Querier interface { + ExpireLeases(ctx context.Context) (int64, error) + GetLeaseInfo(ctx context.Context, key leases.Key) (GetLeaseInfoRow, error) + NewLease(ctx context.Context, key leases.Key, ttl sqltypes.Duration, metadata pqtype.NullRawMessage) (uuid.UUID, error) + ReleaseLease(ctx context.Context, idempotencyKey uuid.UUID, key leases.Key) (bool, error) + RenewLease(ctx context.Context, ttl sqltypes.Duration, idempotencyKey uuid.UUID, key leases.Key) (bool, error) +} + +var _ Querier = (*Queries)(nil) diff --git a/backend/controller/leases/dal/internal/sql/queries.sql b/backend/controller/leases/dal/internal/sql/queries.sql new file mode 100644 index 0000000000..eecec9f808 --- /dev/null +++ b/backend/controller/leases/dal/internal/sql/queries.sql @@ -0,0 +1,37 @@ +-- name: NewLease :one +INSERT INTO leases ( + idempotency_key, + key, + expires_at, + metadata +) +VALUES ( + gen_random_uuid(), + @key::lease_key, + (NOW() AT TIME ZONE 'utc') + @ttl::interval, + sqlc.narg('metadata')::JSONB +) +RETURNING idempotency_key; + +-- name: RenewLease :one +UPDATE leases +SET expires_at = (NOW() AT TIME ZONE 'utc') + @ttl::interval +WHERE idempotency_key = @idempotency_key AND key = @key::lease_key +RETURNING true; + +-- name: ReleaseLease :one +DELETE FROM leases +WHERE idempotency_key = @idempotency_key AND key = @key::lease_key +RETURNING true; + +-- name: ExpireLeases :one +WITH expired AS ( + DELETE FROM leases + WHERE expires_at < NOW() AT TIME ZONE 'utc' + RETURNING 1 +) +SELECT COUNT(*) +FROM expired; + +-- name: GetLeaseInfo :one +SELECT expires_at, metadata FROM leases WHERE key = @key::lease_key; \ No newline at end of file diff --git a/backend/controller/leases/dal/internal/sql/queries.sql.go b/backend/controller/leases/dal/internal/sql/queries.sql.go new file mode 100644 index 0000000000..b809e0d5d8 --- /dev/null +++ b/backend/controller/leases/dal/internal/sql/queries.sql.go @@ -0,0 +1,99 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.27.0 +// source: queries.sql + +package sql + +import ( + "context" + "time" + + "github.com/TBD54566975/ftl/backend/controller/leases" + "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" + "github.com/google/uuid" + "github.com/sqlc-dev/pqtype" +) + +const expireLeases = `-- name: ExpireLeases :one +WITH expired AS ( + DELETE FROM leases + WHERE expires_at < NOW() AT TIME ZONE 'utc' + RETURNING 1 +) +SELECT COUNT(*) +FROM expired +` + +func (q *Queries) ExpireLeases(ctx context.Context) (int64, error) { + row := q.db.QueryRowContext(ctx, expireLeases) + var count int64 + err := row.Scan(&count) + return count, err +} + +const getLeaseInfo = `-- name: GetLeaseInfo :one +SELECT expires_at, metadata FROM leases WHERE key = $1::lease_key +` + +type GetLeaseInfoRow struct { + ExpiresAt time.Time + Metadata pqtype.NullRawMessage +} + +func (q *Queries) GetLeaseInfo(ctx context.Context, key leases.Key) (GetLeaseInfoRow, error) { + row := q.db.QueryRowContext(ctx, getLeaseInfo, key) + var i GetLeaseInfoRow + err := row.Scan(&i.ExpiresAt, &i.Metadata) + return i, err +} + +const newLease = `-- name: NewLease :one +INSERT INTO leases ( + idempotency_key, + key, + expires_at, + metadata +) +VALUES ( + gen_random_uuid(), + $1::lease_key, + (NOW() AT TIME ZONE 'utc') + $2::interval, + $3::JSONB +) +RETURNING idempotency_key +` + +func (q *Queries) NewLease(ctx context.Context, key leases.Key, ttl sqltypes.Duration, metadata pqtype.NullRawMessage) (uuid.UUID, error) { + row := q.db.QueryRowContext(ctx, newLease, key, ttl, metadata) + var idempotency_key uuid.UUID + err := row.Scan(&idempotency_key) + return idempotency_key, err +} + +const releaseLease = `-- name: ReleaseLease :one +DELETE FROM leases +WHERE idempotency_key = $1 AND key = $2::lease_key +RETURNING true +` + +func (q *Queries) ReleaseLease(ctx context.Context, idempotencyKey uuid.UUID, key leases.Key) (bool, error) { + row := q.db.QueryRowContext(ctx, releaseLease, idempotencyKey, key) + var column_1 bool + err := row.Scan(&column_1) + return column_1, err +} + +const renewLease = `-- name: RenewLease :one +UPDATE leases +SET expires_at = (NOW() AT TIME ZONE 'utc') + $1::interval +WHERE idempotency_key = $2 AND key = $3::lease_key +RETURNING true +` + +func (q *Queries) RenewLease(ctx context.Context, ttl sqltypes.Duration, idempotencyKey uuid.UUID, key leases.Key) (bool, error) { + row := q.db.QueryRowContext(ctx, renewLease, ttl, idempotencyKey, key) + var column_1 bool + err := row.Scan(&column_1) + return column_1, err +} diff --git a/backend/controller/leases/dal/lease.go b/backend/controller/leases/dal/lease.go new file mode 100644 index 0000000000..34f524732c --- /dev/null +++ b/backend/controller/leases/dal/lease.go @@ -0,0 +1 @@ +package dal diff --git a/backend/controller/leases/testdata/go/leases/go.mod b/backend/controller/leases/testdata/go/leases/go.mod index 0a802fc57a..6947662351 100644 --- a/backend/controller/leases/testdata/go/leases/go.mod +++ b/backend/controller/leases/testdata/go/leases/go.mod @@ -22,7 +22,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -46,7 +45,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/backend/controller/leases/testdata/go/leases/go.sum b/backend/controller/leases/testdata/go/leases/go.sum index 98987bd625..13edf2824d 100644 --- a/backend/controller/leases/testdata/go/leases/go.sum +++ b/backend/controller/leases/testdata/go/leases/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/backend/controller/sql/migrate/migrate.go b/backend/controller/sql/migrate/migrate.go index 57f8522e9d..32b51bab6d 100644 --- a/backend/controller/sql/migrate/migrate.go +++ b/backend/controller/sql/migrate/migrate.go @@ -15,7 +15,7 @@ import ( "sort" "time" - "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/internal/log" ) @@ -128,8 +128,8 @@ func applyMigration(ctx context.Context, level log.Level, tx *sql.Tx, migration start := time.Now() logger := log.FromContext(ctx).Scope("migrate") _, err := tx.ExecContext(ctx, "INSERT INTO schema_migrations (version) VALUES ($1)", migration.version) - err = dal.TranslatePGError(err) - if errors.Is(err, dal.ErrConflict) { + err = libdal.TranslatePGError(err) + if errors.Is(err, libdal.ErrConflict) { if txerr := tx.Rollback(); txerr != nil { return fmt.Errorf("failed to rollback transaction: %w", txerr) } diff --git a/backend/controller/sql/models.go b/backend/controller/sql/models.go index 039df94a07..49d53f0d84 100644 --- a/backend/controller/sql/models.go +++ b/backend/controller/sql/models.go @@ -415,7 +415,7 @@ type FsmNextEvent struct { FsmInstanceID int64 NextState schema.RefKey Request []byte - RequestType Type + RequestType sqltypes.Type } type IngressRoute struct { diff --git a/backend/controller/sql/querier.go b/backend/controller/sql/querier.go index 738ae45861..8b5c82b3e2 100644 --- a/backend/controller/sql/querier.go +++ b/backend/controller/sql/querier.go @@ -9,14 +9,11 @@ import ( "encoding/json" "time" - "github.com/TBD54566975/ftl/backend/controller/leases" "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/model" "github.com/alecthomas/types/optional" - "github.com/google/uuid" - "github.com/sqlc-dev/pqtype" ) type Querier interface { @@ -39,7 +36,6 @@ type Querier interface { DeleteSubscribers(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriberKey, error) DeleteSubscriptions(ctx context.Context, deployment model.DeploymentKey) ([]model.SubscriptionKey, error) DeregisterRunner(ctx context.Context, key model.RunnerKey) (int64, error) - ExpireLeases(ctx context.Context) (int64, error) ExpireRunnerReservations(ctx context.Context) (int64, error) FailAsyncCall(ctx context.Context, error string, iD int64) (bool, error) FailAsyncCallWithRetry(ctx context.Context, arg FailAsyncCallWithRetryParams) (bool, error) @@ -69,7 +65,6 @@ type Querier interface { GetIdleRunners(ctx context.Context, labels json.RawMessage, limit int64) ([]Runner, error) // Get the runner endpoints corresponding to the given ingress route. GetIngressRoutes(ctx context.Context, method string) ([]GetIngressRoutesRow, error) - GetLeaseInfo(ctx context.Context, key leases.Key) (GetLeaseInfoRow, error) GetModulesByID(ctx context.Context, ids []int64) ([]Module, error) GetNextEventForSubscription(ctx context.Context, consumptionDelay sqltypes.Duration, topic model.TopicKey, cursor optional.Option[model.TopicEventKey]) (GetNextEventForSubscriptionRow, error) GetOnlyEncryptionKey(ctx context.Context) (GetOnlyEncryptionKeyRow, error) @@ -102,11 +97,8 @@ type Querier interface { KillStaleControllers(ctx context.Context, timeout sqltypes.Duration) (int64, error) KillStaleRunners(ctx context.Context, timeout sqltypes.Duration) (int64, error) LoadAsyncCall(ctx context.Context, id int64) (AsyncCall, error) - NewLease(ctx context.Context, key leases.Key, ttl sqltypes.Duration, metadata pqtype.NullRawMessage) (uuid.UUID, error) PopNextFSMEvent(ctx context.Context, fsm schema.RefKey, instanceKey string) (FsmNextEvent, error) PublishEventForTopic(ctx context.Context, arg PublishEventForTopicParams) error - ReleaseLease(ctx context.Context, idempotencyKey uuid.UUID, key leases.Key) (bool, error) - RenewLease(ctx context.Context, ttl sqltypes.Duration, idempotencyKey uuid.UUID, key leases.Key) (bool, error) // Find an idle runner and reserve it for the given deployment. ReserveRunner(ctx context.Context, reservationTimeout time.Time, deploymentKey model.DeploymentKey, labels json.RawMessage) (Runner, error) SetDeploymentDesiredReplicas(ctx context.Context, key model.DeploymentKey, minReplicas int32) error diff --git a/backend/controller/sql/queries.sql b/backend/controller/sql/queries.sql index e7879e3328..261c586b69 100644 --- a/backend/controller/sql/queries.sql +++ b/backend/controller/sql/queries.sql @@ -432,84 +432,6 @@ INSERT INTO timeline (deployment_id, request_id, parent_request_id, type, VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id; --- name: NewLease :one -INSERT INTO leases ( - idempotency_key, - key, - expires_at, - metadata -) -VALUES ( - gen_random_uuid(), - @key::lease_key, - (NOW() AT TIME ZONE 'utc') + @ttl::interval, - sqlc.narg('metadata')::JSONB -) -RETURNING idempotency_key; - --- name: RenewLease :one -UPDATE leases -SET expires_at = (NOW() AT TIME ZONE 'utc') + @ttl::interval -WHERE idempotency_key = @idempotency_key AND key = @key::lease_key -RETURNING true; - --- name: ReleaseLease :one -DELETE FROM leases -WHERE idempotency_key = @idempotency_key AND key = @key::lease_key -RETURNING true; - --- name: ExpireLeases :one -WITH expired AS ( - DELETE FROM leases - WHERE expires_at < NOW() AT TIME ZONE 'utc' - RETURNING 1 -) -SELECT COUNT(*) -FROM expired; - --- name: GetLeaseInfo :one -SELECT expires_at, metadata FROM leases WHERE key = @key::lease_key; - --- name: AcquireAsyncCall :one --- Reserve a pending async call for execution, returning the associated lease --- reservation key and accompanying metadata. -WITH pending_calls AS ( - SELECT id - FROM async_calls - WHERE state = 'pending' AND scheduled_at <= (NOW() AT TIME ZONE 'utc') - ORDER BY created_at -), async_call AS ( - SELECT id - FROM pending_calls - LIMIT 1 - FOR UPDATE SKIP LOCKED -), lease AS ( - INSERT INTO leases (idempotency_key, key, expires_at) - SELECT gen_random_uuid(), '/system/async_call/' || (SELECT id FROM async_call), (NOW() AT TIME ZONE 'utc') + @ttl::interval - WHERE (SELECT id FROM async_call) IS NOT NULL - RETURNING * -) -UPDATE async_calls -SET state = 'executing', lease_id = (SELECT id FROM lease) -WHERE id = (SELECT id FROM async_call) -RETURNING - id AS async_call_id, - (SELECT idempotency_key FROM lease) AS lease_idempotency_key, - (SELECT key FROM lease) AS lease_key, - (SELECT count(*) FROM pending_calls) AS queue_depth, - origin, - verb, - catch_verb, - request, - scheduled_at, - remaining_attempts, - error, - backoff, - max_backoff, - parent_request_key, - trace_context, - catching; - -- name: SucceedAsyncCall :one UPDATE async_calls SET @@ -892,3 +814,43 @@ UPDATE encryption_keys SET verify_timeline = $1, verify_async = $2 WHERE id = 1; + +-- name: AcquireAsyncCall :one +-- Reserve a pending async call for execution, returning the associated lease +-- reservation key and accompanying metadata. +WITH pending_calls AS ( + SELECT id + FROM async_calls + WHERE state = 'pending' AND scheduled_at <= (NOW() AT TIME ZONE 'utc') + ORDER BY created_at +), async_call AS ( + SELECT id + FROM pending_calls + LIMIT 1 + FOR UPDATE SKIP LOCKED +), lease AS ( + INSERT INTO leases (idempotency_key, key, expires_at) + SELECT gen_random_uuid(), '/system/async_call/' || (SELECT id FROM async_call), (NOW() AT TIME ZONE 'utc') + @ttl::interval + WHERE (SELECT id FROM async_call) IS NOT NULL + RETURNING * +) +UPDATE async_calls +SET state = 'executing', lease_id = (SELECT id FROM lease) +WHERE id = (SELECT id FROM async_call) +RETURNING + id AS async_call_id, + (SELECT idempotency_key FROM lease) AS lease_idempotency_key, + (SELECT key FROM lease) AS lease_key, + (SELECT count(*) FROM pending_calls) AS queue_depth, + origin, + verb, + catch_verb, + request, + scheduled_at, + remaining_attempts, + error, + backoff, + max_backoff, + parent_request_key, + trace_context, + catching; \ No newline at end of file diff --git a/backend/controller/sql/queries.sql.go b/backend/controller/sql/queries.sql.go index 1ba65230c0..2492088bb1 100644 --- a/backend/controller/sql/queries.sql.go +++ b/backend/controller/sql/queries.sql.go @@ -368,23 +368,6 @@ func (q *Queries) DeregisterRunner(ctx context.Context, key model.RunnerKey) (in return count, err } -const expireLeases = `-- name: ExpireLeases :one -WITH expired AS ( - DELETE FROM leases - WHERE expires_at < NOW() AT TIME ZONE 'utc' - RETURNING 1 -) -SELECT COUNT(*) -FROM expired -` - -func (q *Queries) ExpireLeases(ctx context.Context) (int64, error) { - row := q.db.QueryRowContext(ctx, expireLeases) - var count int64 - err := row.Scan(&count) - return count, err -} - const expireRunnerReservations = `-- name: ExpireRunnerReservations :one WITH rows AS ( UPDATE runners @@ -1249,22 +1232,6 @@ func (q *Queries) GetIngressRoutes(ctx context.Context, method string) ([]GetIng return items, nil } -const getLeaseInfo = `-- name: GetLeaseInfo :one -SELECT expires_at, metadata FROM leases WHERE key = $1::lease_key -` - -type GetLeaseInfoRow struct { - ExpiresAt time.Time - Metadata pqtype.NullRawMessage -} - -func (q *Queries) GetLeaseInfo(ctx context.Context, key leases.Key) (GetLeaseInfoRow, error) { - row := q.db.QueryRowContext(ctx, getLeaseInfo, key) - var i GetLeaseInfoRow - err := row.Scan(&i.ExpiresAt, &i.Metadata) - return i, err -} - const getModulesByID = `-- name: GetModulesByID :many SELECT id, language, name FROM modules @@ -2249,29 +2216,6 @@ func (q *Queries) LoadAsyncCall(ctx context.Context, id int64) (AsyncCall, error return i, err } -const newLease = `-- name: NewLease :one -INSERT INTO leases ( - idempotency_key, - key, - expires_at, - metadata -) -VALUES ( - gen_random_uuid(), - $1::lease_key, - (NOW() AT TIME ZONE 'utc') + $2::interval, - $3::JSONB -) -RETURNING idempotency_key -` - -func (q *Queries) NewLease(ctx context.Context, key leases.Key, ttl sqltypes.Duration, metadata pqtype.NullRawMessage) (uuid.UUID, error) { - row := q.db.QueryRowContext(ctx, newLease, key, ttl, metadata) - var idempotency_key uuid.UUID - err := row.Scan(&idempotency_key) - return idempotency_key, err -} - const popNextFSMEvent = `-- name: PopNextFSMEvent :one DELETE FROM fsm_next_event WHERE fsm_instance_id = ( @@ -2344,33 +2288,6 @@ func (q *Queries) PublishEventForTopic(ctx context.Context, arg PublishEventForT return err } -const releaseLease = `-- name: ReleaseLease :one -DELETE FROM leases -WHERE idempotency_key = $1 AND key = $2::lease_key -RETURNING true -` - -func (q *Queries) ReleaseLease(ctx context.Context, idempotencyKey uuid.UUID, key leases.Key) (bool, error) { - row := q.db.QueryRowContext(ctx, releaseLease, idempotencyKey, key) - var column_1 bool - err := row.Scan(&column_1) - return column_1, err -} - -const renewLease = `-- name: RenewLease :one -UPDATE leases -SET expires_at = (NOW() AT TIME ZONE 'utc') + $1::interval -WHERE idempotency_key = $2 AND key = $3::lease_key -RETURNING true -` - -func (q *Queries) RenewLease(ctx context.Context, ttl sqltypes.Duration, idempotencyKey uuid.UUID, key leases.Key) (bool, error) { - row := q.db.QueryRowContext(ctx, renewLease, ttl, idempotencyKey, key) - var column_1 bool - err := row.Scan(&column_1) - return column_1, err -} - const reserveRunner = `-- name: ReserveRunner :one UPDATE runners SET state = 'reserved', @@ -2436,7 +2353,7 @@ type SetNextFSMEventParams struct { InstanceKey string Event schema.RefKey Request []byte - RequestType Type + RequestType sqltypes.Type } func (q *Queries) SetNextFSMEvent(ctx context.Context, arg SetNextFSMEventParams) (int64, error) { diff --git a/backend/controller/sql/sqltypes/sqltypes.go b/backend/controller/sql/sqltypes/sqltypes.go index 4fd49d120e..ad397288f2 100644 --- a/backend/controller/sql/sqltypes/sqltypes.go +++ b/backend/controller/sql/sqltypes/sqltypes.go @@ -5,6 +5,11 @@ import ( "fmt" "strings" "time" + + "google.golang.org/protobuf/proto" + + schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema" + "github.com/TBD54566975/ftl/backend/schema" ) type Duration time.Duration @@ -30,3 +35,32 @@ func (d *Duration) Scan(value interface{}) error { return fmt.Errorf("cannot scan duration %v", value) } } + +// Type is a database adapter type for schema.Type. +// +// It encodes to/from the protobuf representation of a Type. +type Type struct { + schema.Type +} + +func (t *Type) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + pb := &schemapb.Type{} + if err := proto.Unmarshal(src, pb); err != nil { + return fmt.Errorf("could not unmarshal type: %w", err) + } + t.Type = schema.TypeFromProto(pb) + return nil + default: + return fmt.Errorf("cannot scan %T", src) + } +} + +func (t Type) Value() (driver.Value, error) { + data, err := proto.Marshal(schema.TypeToProto(t.Type)) + if err != nil { + return nil, fmt.Errorf("could not marshal type: %w", err) + } + return data, nil +} diff --git a/backend/controller/sql/testdata/go/database/go.mod b/backend/controller/sql/testdata/go/database/go.mod index 5008a81dbf..d7b5ad938d 100644 --- a/backend/controller/sql/testdata/go/database/go.mod +++ b/backend/controller/sql/testdata/go/database/go.mod @@ -19,7 +19,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -43,7 +42,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/backend/controller/sql/testdata/go/database/go.sum b/backend/controller/sql/testdata/go/database/go.sum index 98987bd625..13edf2824d 100644 --- a/backend/controller/sql/testdata/go/database/go.sum +++ b/backend/controller/sql/testdata/go/database/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/backend/controller/sql/types.go b/backend/controller/sql/types.go deleted file mode 100644 index 86f62d2c75..0000000000 --- a/backend/controller/sql/types.go +++ /dev/null @@ -1,40 +0,0 @@ -package sql - -import ( - "database/sql/driver" - "fmt" - - "google.golang.org/protobuf/proto" - - schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema" - "github.com/TBD54566975/ftl/backend/schema" -) - -// Type is a database adapter type for schema.Type. -// -// It encodes to/from the protobuf representation of a Type. -type Type struct { - schema.Type -} - -func (t *Type) Scan(src interface{}) error { - switch src := src.(type) { - case []byte: - pb := &schemapb.Type{} - if err := proto.Unmarshal(src, pb); err != nil { - return fmt.Errorf("could not unmarshal type: %w", err) - } - t.Type = schema.TypeFromProto(pb) - return nil - default: - return fmt.Errorf("cannot scan %T", src) - } -} - -func (t Type) Value() (driver.Value, error) { - data, err := proto.Marshal(schema.TypeToProto(t.Type)) - if err != nil { - return nil, err - } - return data, nil -} diff --git a/backend/dal/errors.go b/backend/libdal/errors.go similarity index 94% rename from backend/dal/errors.go rename to backend/libdal/errors.go index 867b773810..f6f5c7dbf9 100644 --- a/backend/dal/errors.go +++ b/backend/libdal/errors.go @@ -1,9 +1,9 @@ -// Package dal provides common types and functions for domain-specific DALs. +// Package libdal provides common types and functions for domain-specific DALs. // // In particular, common error types and error handling function for all // domain-specific DALs, e.g. controller DAL and configuration DAL, which all // connect to the same underlying DB and maintain the same interface guarantees -package dal +package libdal import ( stdsql "database/sql" diff --git a/backend/dal/dal.go b/backend/libdal/libdal.go similarity index 99% rename from backend/dal/dal.go rename to backend/libdal/libdal.go index 14fcb3de47..e417f778be 100644 --- a/backend/dal/dal.go +++ b/backend/libdal/libdal.go @@ -1,4 +1,4 @@ -package dal +package libdal import ( "context" diff --git a/backend/dal/dal_test.go b/backend/libdal/libdal_test.go similarity index 99% rename from backend/dal/dal_test.go rename to backend/libdal/libdal_test.go index 22140afe47..10a7a871c7 100644 --- a/backend/dal/dal_test.go +++ b/backend/libdal/libdal_test.go @@ -1,4 +1,4 @@ -package dal +package libdal import ( "context" diff --git a/bin/.dlv-1.23.0.pkg b/bin/.dlv-1.23.0.pkg deleted file mode 120000 index 383f4511d4..0000000000 --- a/bin/.dlv-1.23.0.pkg +++ /dev/null @@ -1 +0,0 @@ -hermit \ No newline at end of file diff --git a/bin/delve-1.23.0 b/bin/delve-1.23.0 deleted file mode 120000 index d300745168..0000000000 --- a/bin/delve-1.23.0 +++ /dev/null @@ -1 +0,0 @@ -.dlv-1.23.0.pkg \ No newline at end of file diff --git a/cmd/ftl-controller/main.go b/cmd/ftl-controller/main.go index d95d054855..89b9099c48 100644 --- a/cmd/ftl-controller/main.go +++ b/cmd/ftl-controller/main.go @@ -8,18 +8,16 @@ import ( "time" "github.com/alecthomas/kong" - "github.com/alecthomas/types/optional" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/TBD54566975/ftl" "github.com/TBD54566975/ftl/backend/controller" - "github.com/TBD54566975/ftl/backend/controller/dal" + leasesdal "github.com/TBD54566975/ftl/backend/controller/leases/dal" "github.com/TBD54566975/ftl/backend/controller/scaling" _ "github.com/TBD54566975/ftl/internal/automaxprocs" // Set GOMAXPROCS to match Linux container CPU quota. cf "github.com/TBD54566975/ftl/internal/configuration" cfdal "github.com/TBD54566975/ftl/internal/configuration/dal" - "github.com/TBD54566975/ftl/internal/encryption" "github.com/TBD54566975/ftl/internal/log" "github.com/TBD54566975/ftl/internal/observability" ) @@ -56,9 +54,7 @@ func main() { conn, err := observability.OpenDBAndInstrument(cli.ControllerConfig.DSN) kctx.FatalIfErrorf(err) - encryptionBuilder := encryption.NewBuilder().WithKMSURI(optional.Ptr(cli.ControllerConfig.KMSURI)) - kctx.FatalIfErrorf(err) - dal, err := dal.New(ctx, conn, encryptionBuilder) + dal := leasesdal.New(conn) kctx.FatalIfErrorf(err) configDal := cfdal.New(conn) diff --git a/go-runtime/ftl/ftltest/testdata/go/pubsub/go.mod b/go-runtime/ftl/ftltest/testdata/go/pubsub/go.mod index 4776e13bc7..91c805c8fe 100644 --- a/go-runtime/ftl/ftltest/testdata/go/pubsub/go.mod +++ b/go-runtime/ftl/ftltest/testdata/go/pubsub/go.mod @@ -19,7 +19,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -43,7 +42,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/go-runtime/ftl/ftltest/testdata/go/pubsub/go.sum b/go-runtime/ftl/ftltest/testdata/go/pubsub/go.sum index 98987bd625..13edf2824d 100644 --- a/go-runtime/ftl/ftltest/testdata/go/pubsub/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/pubsub/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/go-runtime/ftl/ftltest/testdata/go/subscriber/go.mod b/go-runtime/ftl/ftltest/testdata/go/subscriber/go.mod index f4aa36eb96..7ba8e36970 100644 --- a/go-runtime/ftl/ftltest/testdata/go/subscriber/go.mod +++ b/go-runtime/ftl/ftltest/testdata/go/subscriber/go.mod @@ -19,7 +19,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -43,7 +42,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/go-runtime/ftl/ftltest/testdata/go/subscriber/go.sum b/go-runtime/ftl/ftltest/testdata/go/subscriber/go.sum index 98987bd625..13edf2824d 100644 --- a/go-runtime/ftl/ftltest/testdata/go/subscriber/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/subscriber/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.mod b/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.mod index 2d8b5e97c3..e19e3036cc 100644 --- a/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.mod +++ b/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.mod @@ -21,7 +21,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -45,7 +44,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.sum b/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.sum index 98987bd625..13edf2824d 100644 --- a/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/verbtypes/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/go-runtime/ftl/ftltest/testdata/go/wrapped/go.mod b/go-runtime/ftl/ftltest/testdata/go/wrapped/go.mod index bc11720b74..7a5b93fdeb 100644 --- a/go-runtime/ftl/ftltest/testdata/go/wrapped/go.mod +++ b/go-runtime/ftl/ftltest/testdata/go/wrapped/go.mod @@ -19,7 +19,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -43,7 +42,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/go-runtime/ftl/ftltest/testdata/go/wrapped/go.sum b/go-runtime/ftl/ftltest/testdata/go/wrapped/go.sum index 98987bd625..13edf2824d 100644 --- a/go-runtime/ftl/ftltest/testdata/go/wrapped/go.sum +++ b/go-runtime/ftl/ftltest/testdata/go/wrapped/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/go-runtime/ftl/testdata/go/mapper/go.mod b/go-runtime/ftl/testdata/go/mapper/go.mod index 9495d2da5d..36272c5a64 100644 --- a/go-runtime/ftl/testdata/go/mapper/go.mod +++ b/go-runtime/ftl/testdata/go/mapper/go.mod @@ -19,7 +19,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -43,7 +42,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/go-runtime/ftl/testdata/go/mapper/go.sum b/go-runtime/ftl/testdata/go/mapper/go.sum index 98987bd625..13edf2824d 100644 --- a/go-runtime/ftl/testdata/go/mapper/go.sum +++ b/go-runtime/ftl/testdata/go/mapper/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/go-runtime/ftl/testdata/go/typeregistry/go.mod b/go-runtime/ftl/testdata/go/typeregistry/go.mod index 4e54052ec1..34acc4f2e5 100644 --- a/go-runtime/ftl/testdata/go/typeregistry/go.mod +++ b/go-runtime/ftl/testdata/go/typeregistry/go.mod @@ -19,7 +19,6 @@ require ( github.com/alecthomas/repr v0.4.0 // indirect github.com/alecthomas/types v0.16.0 // indirect github.com/alessio/shellescape v1.4.2 // indirect - github.com/amacneil/dbmate/v2 v2.20.0 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect github.com/aws/aws-sdk-go-v2 v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect @@ -43,7 +42,6 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect diff --git a/go-runtime/ftl/testdata/go/typeregistry/go.sum b/go-runtime/ftl/testdata/go/typeregistry/go.sum index 98987bd625..13edf2824d 100644 --- a/go-runtime/ftl/testdata/go/typeregistry/go.sum +++ b/go-runtime/ftl/testdata/go/typeregistry/go.sum @@ -4,8 +4,6 @@ connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/TBD54566975/scaffolder v1.1.0 h1:R92zjC4XiS/lGCxJ8Ebn93g8gC0LU9qo06AAKo9cEJE= @@ -82,8 +80,6 @@ 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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -122,8 +118,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= @@ -165,8 +159,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= -github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= 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/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= @@ -200,7 +192,6 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22duwci1+TG7bg2/L1LQsXwfjPlmuJA0= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= diff --git a/internal/configuration/dal/dal.go b/internal/configuration/dal/dal.go index b77ea16287..6d4a7ff158 100644 --- a/internal/configuration/dal/dal.go +++ b/internal/configuration/dal/dal.go @@ -7,19 +7,19 @@ import ( "github.com/alecthomas/types/optional" - "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/internal/configuration/sql" ) type DAL struct { - *dal.Handle[DAL] + *libdal.Handle[DAL] db sql.Querier } -func New(conn dal.Connection) *DAL { +func New(conn libdal.Connection) *DAL { return &DAL{ db: sql.New(conn), - Handle: dal.New(conn, func(h *dal.Handle[DAL]) *DAL { + Handle: libdal.New(conn, func(h *libdal.Handle[DAL]) *DAL { return &DAL{Handle: h, db: sql.New(h.Connection)} }), } @@ -28,25 +28,25 @@ func New(conn dal.Connection) *DAL { func (d *DAL) GetModuleConfiguration(ctx context.Context, module optional.Option[string], name string) ([]byte, error) { b, err := d.db.GetModuleConfiguration(ctx, module, name) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return b, nil } func (d *DAL) SetModuleConfiguration(ctx context.Context, module optional.Option[string], name string, value []byte) error { err := d.db.SetModuleConfiguration(ctx, module, name, value) - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } func (d *DAL) UnsetModuleConfiguration(ctx context.Context, module optional.Option[string], name string) error { err := d.db.UnsetModuleConfiguration(ctx, module, name) - return dal.TranslatePGError(err) + return libdal.TranslatePGError(err) } func (d *DAL) ListModuleConfiguration(ctx context.Context) ([]sql.ModuleConfiguration, error) { l, err := d.db.ListModuleConfiguration(ctx) if err != nil { - return nil, dal.TranslatePGError(err) + return nil, libdal.TranslatePGError(err) } return l, nil } @@ -54,7 +54,7 @@ func (d *DAL) ListModuleConfiguration(ctx context.Context) ([]sql.ModuleConfigur func (d *DAL) GetModuleSecretURL(ctx context.Context, module optional.Option[string], name string) (string, error) { b, err := d.db.GetModuleSecretURL(ctx, module, name) if err != nil { - return "", fmt.Errorf("could not get secret URL: %w", dal.TranslatePGError(err)) + return "", fmt.Errorf("could not get secret URL: %w", libdal.TranslatePGError(err)) } return b, nil } @@ -62,7 +62,7 @@ func (d *DAL) GetModuleSecretURL(ctx context.Context, module optional.Option[str func (d *DAL) SetModuleSecretURL(ctx context.Context, module optional.Option[string], name string, url string) error { err := d.db.SetModuleSecretURL(ctx, module, name, url) if err != nil { - return fmt.Errorf("could not set secret URL: %w", dal.TranslatePGError(err)) + return fmt.Errorf("could not set secret URL: %w", libdal.TranslatePGError(err)) } return nil } @@ -70,7 +70,7 @@ func (d *DAL) SetModuleSecretURL(ctx context.Context, module optional.Option[str func (d *DAL) UnsetModuleSecret(ctx context.Context, module optional.Option[string], name string) error { err := d.db.UnsetModuleSecret(ctx, module, name) if err != nil { - return fmt.Errorf("could not unset secret: %w", dal.TranslatePGError(err)) + return fmt.Errorf("could not unset secret: %w", libdal.TranslatePGError(err)) } return nil } @@ -80,7 +80,7 @@ type ModuleSecret sql.ModuleSecret func (d *DAL) ListModuleSecrets(ctx context.Context) ([]ModuleSecret, error) { l, err := d.db.ListModuleSecrets(ctx) if err != nil { - return nil, fmt.Errorf("could not list secrets: %w", dal.TranslatePGError(err)) + return nil, fmt.Errorf("could not list secrets: %w", libdal.TranslatePGError(err)) } // Convert []sql.ModuleSecret to []ModuleSecret diff --git a/internal/configuration/dal/dal_test.go b/internal/configuration/dal/dal_test.go index d673648693..d49e67e55c 100644 --- a/internal/configuration/dal/dal_test.go +++ b/internal/configuration/dal/dal_test.go @@ -10,7 +10,7 @@ import ( "github.com/alecthomas/types/optional" "github.com/TBD54566975/ftl/backend/controller/sql/sqltest" - libdal "github.com/TBD54566975/ftl/backend/dal" + libdal "github.com/TBD54566975/ftl/backend/libdal" "github.com/TBD54566975/ftl/internal/log" ) diff --git a/internal/configuration/db_config_provider.go b/internal/configuration/db_config_provider.go index ea306357c5..ade54988a0 100644 --- a/internal/configuration/db_config_provider.go +++ b/internal/configuration/db_config_provider.go @@ -6,7 +6,7 @@ import ( "github.com/alecthomas/types/optional" - dalerrs "github.com/TBD54566975/ftl/backend/dal" + "github.com/TBD54566975/ftl/backend/libdal" ) // DBConfigProvider is a configuration provider that stores configuration in its key. @@ -34,7 +34,7 @@ func (DBConfigProvider) Key() string { return "db" } func (d DBConfigProvider) Load(ctx context.Context, ref Ref, key *url.URL) ([]byte, error) { value, err := d.dal.GetModuleConfiguration(ctx, ref.Module, ref.Name) if err != nil { - return nil, dalerrs.ErrNotFound + return nil, libdal.ErrNotFound } return value, nil } diff --git a/internal/configuration/sql/models.go b/internal/configuration/sql/models.go index 039df94a07..49d53f0d84 100644 --- a/internal/configuration/sql/models.go +++ b/internal/configuration/sql/models.go @@ -415,7 +415,7 @@ type FsmNextEvent struct { FsmInstanceID int64 NextState schema.RefKey Request []byte - RequestType Type + RequestType sqltypes.Type } type IngressRoute struct { diff --git a/internal/configuration/sql/types.go b/internal/configuration/sql/types.go index 31097b10c6..e369443cd8 100644 --- a/internal/configuration/sql/types.go +++ b/internal/configuration/sql/types.go @@ -1,5 +1,5 @@ package sql -import csql "github.com/TBD54566975/ftl/backend/controller/sql" +import "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes" -type Type = csql.Type +type Type = sqltypes.Type diff --git a/sqlc.yaml b/sqlc.yaml index cb69797a10..fdd8446c8c 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -53,8 +53,7 @@ sql: go_type: type: "optional.Option[schema.RefKey]" - db_type: "schema_type" - go_type: - type: "Type" + go_type: "github.com/TBD54566975/ftl/backend/controller/sql/sqltypes.Type" - db_type: "schema_type" nullable: true go_type: @@ -163,6 +162,13 @@ sql: go: <<: *gengo out: "internal/configuration/sql" + - <<: *daldir + queries: + - backend/controller/leases/dal/internal/sql/queries.sql + gen: + go: + <<: *gengo + out: "backend/controller/leases/dal/internal/sql" rules: - name: postgresql-query-too-costly message: "Query cost estimate is too high"