fleet-console: Extend ent so our code can look prettier Change-Id: I43e4f4c77845a7125414b3a5bd45f8d5bc26926a Reviewed-on: https://chromium-review.googlesource.com/c/infra/infra/+/7494081 Auto-Submit: Vaghinak Vardanyan <vaghinak@google.com> Reviewed-by: Pietro Scuttari <pietroscutta@google.com> Commit-Queue: Vaghinak Vardanyan <vaghinak@google.com> Reviewed-by: Konrad Polarczyk <polarczyk@google.com> Cr-Commit-Position: refs/heads/main@{#78483}
diff --git a/go/src/infra/fleetconsole/internal/database/browser_devicedb/count_devices.go b/go/src/infra/fleetconsole/internal/database/browser_devicedb/count_devices.go index f0c8cbe..b8f5b11 100644 --- a/go/src/infra/fleetconsole/internal/database/browser_devicedb/count_devices.go +++ b/go/src/infra/fleetconsole/internal/database/browser_devicedb/count_devices.go
@@ -18,7 +18,6 @@ ent "go.chromium.org/infra/fleetconsole/internal/ent/generated" "go.chromium.org/infra/fleetconsole/internal/ent/generated/browserdevice" "go.chromium.org/infra/fleetconsole/internal/ent/generated/migrate" - "go.chromium.org/infra/fleetconsole/internal/ent/generated/predicate" "go.chromium.org/infra/fleetconsole/internal/swarmingclient" ) @@ -33,25 +32,17 @@ // CountDevices calculates browser devices related metrics. func CountDevices(ctx context.Context, filter string, realms []string) (*fleetconsolerpc.CountBrowserDevicesResponse, error) { var rows []DeviceCounts - client := database.GetEntClient(ctx) p, err := queryutils.ToEntPredicate(filter, migrate.BrowserDevicesTable) if err != nil { return nil, errors.Fmt("failed to parse filter: %w", err) } - q := client.BrowserDevice.Query().Where(p) - - if realms != nil { - realmChecks := []predicate.BrowserDevice{browserdevice.RealmIsNil()} - if len(realms) > 0 { - realmChecks = append(realmChecks, browserdevice.RealmIn(realms...)) - } - q.Where(browserdevice.Or(realmChecks...)) - } - jsonPath := sqljson.Path("state") - err = q. + database.GetEntClient(ctx).BrowserDevice. + Query(). + Where(p). + Where(entx.RealmFilter(browserdevice.FieldRealm, realms)). Aggregate( ent.As(ent.Count(), "total"), ent.As(entx.CountIf(sqljson.ValueContains(browserdevice.FieldSwarmingLabels, string(swarmingclient.Alive), jsonPath)), string(swarmingclient.Alive)),
diff --git a/go/src/infra/fleetconsole/internal/database/browser_devicedb/list.go b/go/src/infra/fleetconsole/internal/database/browser_devicedb/list.go index 38229b3..8211f4b 100644 --- a/go/src/infra/fleetconsole/internal/database/browser_devicedb/list.go +++ b/go/src/infra/fleetconsole/internal/database/browser_devicedb/list.go
@@ -12,40 +12,33 @@ "go.chromium.org/infra/fleetconsole/api/fleetconsolerpc" "go.chromium.org/infra/fleetconsole/internal/database" "go.chromium.org/infra/fleetconsole/internal/database/queryutils" + "go.chromium.org/infra/fleetconsole/internal/ent/entx" "go.chromium.org/infra/fleetconsole/internal/ent/generated/browserdevice" "go.chromium.org/infra/fleetconsole/internal/ent/generated/migrate" - "go.chromium.org/infra/fleetconsole/internal/ent/generated/predicate" "go.chromium.org/infra/fleetconsole/internal/utils" ) // List lists the devices from the database. func List(ctx context.Context, filter, orderby string, offset, pageSize int, realms []string) ([]*fleetconsolerpc.BrowserDevice, bool, error) { - q := database.GetEntClient(ctx).BrowserDevice.Query() - p, err := queryutils.ToEntPredicate(filter, migrate.BrowserDevicesTable) if err != nil { return nil, false, errors.Fmt("failed to parse filter: %w", err) } - q.Where(p) - - if realms != nil { - realmChecks := []predicate.BrowserDevice{browserdevice.RealmIsNil()} - if len(realms) > 0 { - realmChecks = append(realmChecks, browserdevice.RealmIn(realms...)) - } - q.Where(browserdevice.Or(realmChecks...)) - } o, err := queryutils.ToEntOrderBy(orderby, migrate.BrowserDevicesTable, browserdevice.FieldID) if err != nil { return nil, false, utils.InvalidOrderByError(err) } - q.Order(o) // Fetch one extra row to check whether there is more data available - q.Offset(offset).Limit(pageSize + 1) + entities, err := database.GetEntClient(ctx).BrowserDevice. + Query(). + Where(p). + Where(entx.RealmFilter(browserdevice.FieldRealm, realms)). + Order(o). + Offset(offset).Limit(pageSize + 1). + All(ctx) - entities, err := q.All(ctx) if err != nil { return nil, false, errors.Fmt("failed to list devices: %w", err) }
diff --git a/go/src/infra/fleetconsole/internal/database/browser_devicedb/total_count.go b/go/src/infra/fleetconsole/internal/database/browser_devicedb/total_count.go index f420ca7..0bca0de 100644 --- a/go/src/infra/fleetconsole/internal/database/browser_devicedb/total_count.go +++ b/go/src/infra/fleetconsole/internal/database/browser_devicedb/total_count.go
@@ -11,28 +11,22 @@ "go.chromium.org/infra/fleetconsole/internal/database" "go.chromium.org/infra/fleetconsole/internal/database/queryutils" + "go.chromium.org/infra/fleetconsole/internal/ent/entx" "go.chromium.org/infra/fleetconsole/internal/ent/generated/browserdevice" "go.chromium.org/infra/fleetconsole/internal/ent/generated/migrate" - "go.chromium.org/infra/fleetconsole/internal/ent/generated/predicate" ) // TotalCount counts the devices in the database. func TotalCount(ctx context.Context, filter string, realms []string) (int, error) { - q := database.GetEntClient(ctx).BrowserDevice.Query() p, err := queryutils.ToEntPredicate(filter, migrate.BrowserDevicesTable) if err != nil { return 0, errors.Fmt("failed to parse filter: %w", err) } - q.Where(p) - if realms != nil { - realmChecks := []predicate.BrowserDevice{browserdevice.RealmIsNil()} - if len(realms) > 0 { - realmChecks = append(realmChecks, browserdevice.RealmIn(realms...)) - } - q.Where(browserdevice.Or(realmChecks...)) - } - - return q.Count(ctx) + return database.GetEntClient(ctx).BrowserDevice. + Query(). + Where(p). + Where(entx.RealmFilter(browserdevice.FieldRealm, realms)). + Count(ctx) }
diff --git a/go/src/infra/fleetconsole/internal/ent/entx/filter.go b/go/src/infra/fleetconsole/internal/ent/entx/filter.go new file mode 100644 index 0000000..7e0078d --- /dev/null +++ b/go/src/infra/fleetconsole/internal/ent/entx/filter.go
@@ -0,0 +1,40 @@ +// Copyright 2026 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package entx + +import ( + "entgo.io/ent/dialect/sql" + + "go.chromium.org/infra/fleetconsole/internal/utils" +) + +// RealmFilter returns a generic predicate that works on ANY Ent query. +// It assumes the underlying table has a column named "realm". +func RealmFilter(col string, realms []string) func(*sql.Selector) { + return func(s *sql.Selector) { + // If nil, apply no filter + if realms == nil { + return + } + + // s.C resolves to "table_name"."col_name" to avoid ambiguity + col := s.C(col) + + nilCheck := sql.IsNull(col) + if len(realms) == 0 { + s.Where(nilCheck) + return + } + + // Convert []string to []any for the sql builder + args := utils.Map(realms, func(realm string) any { return realm }) + + // (realm IS NULL) OR (realm IN (...)) + s.Where(sql.Or( + nilCheck, + sql.In(col, args...), + )) + } +}