@@ -46,7 +46,10 @@ type ServiceIDOrNameOptions struct {
4646}
4747
4848type DeleteOptions struct {
49+ // IDs filters containers by their container IDs.
4950 IDs []string
51+ // MachineIDs filters containers by the machine IDs they are running on.
52+ MachineIDs []string
5053}
5154
5255// CreateOrUpdateContainer creates a new container record or updates an existing one in the store database.
@@ -100,21 +103,24 @@ func normaliseContainerForStore(ctr *api.ServiceContainer) {
100103}
101104
102105// ListContainers returns a list of container records from the store database that match the given options.
106+ // The result excludes orphan containers whose machine is no longer in the cluster.
103107func (s * Store ) ListContainers (ctx context.Context , opts ListOptions ) ([]ContainerRecord , error ) {
104- q := sq .Select ("id" , "container" , "machine_id" , "sync_status" , "updated_at" ).From ("containers" ).
105- Where (sq.Eq {"sync_status" : SyncStatusSynced })
108+ q := sq .Select ("c.id" , "c.container" , "c.machine_id" , "c.sync_status" , "c.updated_at" ).
109+ From ("containers c" ).
110+ Join ("machines m ON m.id = c.machine_id" ).
111+ Where (sq.Eq {"c.sync_status" : SyncStatusSynced })
106112
107113 if len (opts .MachineIDs ) > 0 {
108- q = q .Where (sq.Eq {"machine_id" : opts .MachineIDs })
114+ q = q .Where (sq.Eq {"c. machine_id" : opts .MachineIDs })
109115 }
110116
111117 if opts .ServiceIDOrName .ID != "" || opts .ServiceIDOrName .Name != "" {
112118 var conditions []sq.Sqlizer
113119 if opts .ServiceIDOrName .ID != "" {
114- conditions = append (conditions , sq.Eq {"service_id" : opts .ServiceIDOrName .ID })
120+ conditions = append (conditions , sq.Eq {"c. service_id" : opts .ServiceIDOrName .ID })
115121 }
116122 if opts .ServiceIDOrName .Name != "" {
117- conditions = append (conditions , sq.Eq {"service_name" : opts .ServiceIDOrName .Name })
123+ conditions = append (conditions , sq.Eq {"c. service_name" : opts .ServiceIDOrName .Name })
118124 }
119125 q = q .Where (sq .Or (conditions ))
120126 }
@@ -172,35 +178,42 @@ func (s *Store) ListContainers(ctx context.Context, opts ListOptions) ([]Contain
172178}
173179
174180// DeleteContainers deletes container records from the store database that match the given options.
181+ // If no filter is set, all container records are deleted. Filters are combined with AND.
175182func (s * Store ) DeleteContainers (ctx context.Context , opts DeleteOptions ) error {
176- query := "DELETE FROM containers"
177- var args []any
178-
183+ q := sq .Delete ("containers" )
179184 if len (opts .IDs ) > 0 {
180- query += " WHERE id IN (?" + strings .Repeat (", ?" , len (opts .IDs )- 1 ) + ")"
181- args = make ([]any , len (opts .IDs ))
182- for i , id := range opts .IDs {
183- args [i ] = id
184- }
185+ q = q .Where (sq.Eq {"id" : opts .IDs })
186+ }
187+ if len (opts .MachineIDs ) > 0 {
188+ q = q .Where (sq.Eq {"machine_id" : opts .MachineIDs })
189+ }
190+
191+ query , args , err := q .ToSql ()
192+ if err != nil {
193+ return fmt .Errorf ("build query: %w" , err )
185194 }
186195
187196 res , err := s .corro .ExecContext (ctx , query , args ... )
188197 if err != nil {
189198 return fmt .Errorf ("delete query: %w" , err )
190199 }
191200 if res .RowsAffected > 0 {
192- slog .Debug ("Container records deleted from store DB." , "ids" , opts .IDs , "count" , res .RowsAffected )
201+ slog .Debug ("Container records deleted from store DB." ,
202+ "ids" , opts .IDs , "machine_ids" , opts .MachineIDs , "count" , res .RowsAffected )
193203 }
194204
195205 return nil
196206}
197207
198208// SubscribeContainers returns a list of containers and a channel that signals changes to the list. The channel doesn't
199209// receive any values, it just signals when a container(s) has been added, updated, or deleted in the database.
210+ // The result excludes orphan containers whose machine is no longer in the cluster.
200211func (s * Store ) SubscribeContainers (ctx context.Context ) ([]ContainerRecord , <- chan struct {}, error ) {
201212 // TODO: figure out whether we need sync_status at all (not used at the moment).
202- q := sq .Select ("id" , "container" , "machine_id" , "sync_status" , "updated_at" ).From ("containers" ).
203- Where (sq.Eq {"sync_status" : SyncStatusSynced })
213+ q := sq .Select ("c.id" , "c.container" , "c.machine_id" , "c.sync_status" , "c.updated_at" ).
214+ From ("containers c" ).
215+ Join ("machines m ON m.id = c.machine_id" ).
216+ Where (sq.Eq {"c.sync_status" : SyncStatusSynced })
204217 query , args , err := q .ToSql ()
205218 if err != nil {
206219 return nil , nil , fmt .Errorf ("build query: %w" , err )
0 commit comments