Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use FilterEntity instead of Filter #3703

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion api/checks/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ func (s checksAPIImpl) ScheduleResultsProcessing(sha string, product shared.Prod
func (s checksAPIImpl) GetSuitesForSHA(sha string) ([]shared.CheckSuite, error) {
var suites []shared.CheckSuite
store := shared.NewAppEngineDatastore(s.Context(), false)
_, err := store.GetAll(store.NewQuery("CheckSuite").Filter("SHA =", sha), &suites)
q := store.NewQuery("CheckSuite")
_, err := store.GetAll(q.FilterEntity(q.FilterBuilder().PropertyFilter("SHA", "=", sha)), &suites)

return suites, err
}
Expand Down
14 changes: 8 additions & 6 deletions api/checks/suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ func getOrCreateCheckSuite(
prNumbers ...int,
) (*shared.CheckSuite, error) {
ds := shared.NewAppEngineDatastore(ctx, false)
query := ds.NewQuery("CheckSuite").
Filter("SHA =", sha).
Filter("AppID =", appID).
Filter("InstallationID =", installationID).
Filter("Owner =", owner).
Filter("Repo =", repo).
query := ds.NewQuery("CheckSuite")
filterBuilder := query.FilterBuilder()
query = query.
FilterEntity(filterBuilder.PropertyFilter("SHA", "=", sha)).
FilterEntity(filterBuilder.PropertyFilter("AppID", "=", appID)).
FilterEntity(filterBuilder.PropertyFilter("InstallationID", "=", installationID)).
FilterEntity(filterBuilder.PropertyFilter("Owner", "=", owner)).
FilterEntity(filterBuilder.PropertyFilter("Repo", "=", repo)).
KeysOnly()
var suite shared.CheckSuite
if keys, err := ds.GetAll(query, nil); err != nil {
Expand Down
9 changes: 5 additions & 4 deletions api/pending_test_runs.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ func apiPendingTestRunsHandler(w http.ResponseWriter, r *http.Request) {

filter := strings.ToLower(mux.Vars(r)["filter"])
q := store.NewQuery("PendingTestRun")
filterBuilder := q.FilterBuilder()
switch filter {
case "pending":
q = q.Order("-Stage").Filter("Stage < ", int(shared.StageValid))
q = q.Order("-Stage").FilterEntity(filterBuilder.PropertyFilter("Stage", "<", int(shared.StageValid)))
case "invalid":
q = q.Filter("Stage = ", int(shared.StageInvalid))
q = q.FilterEntity(filterBuilder.PropertyFilter("Stage", "=", int(shared.StageInvalid)))
case "empty":
q = q.Filter("Stage = ", int(shared.StageEmpty))
q = q.FilterEntity(filterBuilder.PropertyFilter("Stage", "=", int(shared.StageEmpty)))
case "duplicate":
q = q.Filter("Stage = ", int(shared.StageDuplicate))
q = q.FilterEntity(filterBuilder.PropertyFilter("Stage", "= ", int(shared.StageDuplicate)))
case "":
// No-op
default:
Expand Down
2 changes: 1 addition & 1 deletion api/screenshot/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func RecentScreenshotHashes(
for all.Cardinality() < totalLimit {
query := ds.NewQuery("Screenshot")
for _, l := range labels {
query = query.Filter("Labels =", l)
query = query.FilterEntity(query.FilterBuilder().PropertyFilter("Labels", "=", l))
}
query = query.Order("-LastUsed").Limit(totalLimit)

Expand Down
3 changes: 2 additions & 1 deletion api/test_history.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ func testHistoryHandler(w http.ResponseWriter, r *http.Request) {
}

store := shared.NewAppEngineDatastore(ctx, false)
q := store.NewQuery("TestHistoryEntry").Filter("TestName =", reqBody.TestName)
q := store.NewQuery("TestHistoryEntry")
q = q.FilterEntity(q.FilterBuilder().PropertyFilter("TestName", "=", reqBody.TestName))

var runs []shared.TestHistoryEntry
_, err = store.GetAll(q, &runs)
Expand Down
8 changes: 5 additions & 3 deletions api/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@ func (h VersionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

ctx := h.ctx
store := shared.NewAppEngineDatastore(ctx, false)
query := store.NewQuery("TestRun").Filter("BrowserName =", product.BrowserName)
query := store.NewQuery("TestRun")
filterBuilder := query.FilterBuilder()
query = query.FilterEntity(filterBuilder.PropertyFilter("BrowserName", "=", product.BrowserName))
if product.Labels != nil {
for label := range product.Labels.Iter() {
query = query.Filter("Labels =", label)
query = query.FilterEntity(filterBuilder.PropertyFilter("Labels", "=", label))
}
}
distinctQuery := query.Project("BrowserVersion").Distinct()
Expand All @@ -61,7 +63,7 @@ func (h VersionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
queries = []shared.Query{distinctQuery}
} else {
queries = []shared.Query{
query.Filter("BrowserVersion =", product.BrowserVersion).Limit(1),
query.FilterEntity(filterBuilder.PropertyFilter("BrowserVersion", "=", product.BrowserVersion)).Limit(1),
shared.VersionPrefix(distinctQuery, "BrowserVersion", product.BrowserVersion, false /*desc*/),
}
}
Expand Down
14 changes: 13 additions & 1 deletion shared/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,26 @@ type Iterator interface {

// Query abstracts a datastore.Query
type Query interface {
Filter(filterStr string, value interface{}) Query
FilterEntity(EntityFilter) Query
Project(fields ...string) Query
Limit(limit int) Query
Offset(offset int) Query
Order(order string) Query
KeysOnly() Query
Distinct() Query
Run(Datastore) Iterator

FilterBuilder() FilterBuilder
}

// PropertyFilter is a particular filter that filters based on property value.
type PropertyFilter interface {
EntityFilter
}

// FilterBuilder contains the logic to create different types of filters
type FilterBuilder interface {
PropertyFilter(FieldName string, Operator string, Value interface{}) EntityFilter
}

// Datastore abstracts a datastore, hiding the distinctions between cloud and
Expand Down
21 changes: 21 additions & 0 deletions shared/datastore_cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ type cloudQuery struct {
query *datastore.Query
}

func (q cloudQuery) FilterBuilder() FilterBuilder {
return cloudFilterBuilder{}
}

func (q cloudQuery) FilterEntity(entityFilter EntityFilter) Query {
return cloudQuery{q.query.FilterEntity(entityFilter)}
}

func (q cloudQuery) Filter(filterStr string, value interface{}) Query {
return cloudQuery{q.query.Filter(filterStr, value)}
}
Expand Down Expand Up @@ -240,3 +248,16 @@ func (i cloudIterator) Next(dst interface{}) (Key, error) {
key, err := i.iter.Next(dst)
return cloudKey{key}, err
}

// EntityFilter wraps datastore.EntityFilter.
// datastore.EntityFilter does not expose any methods. But using this type
// allows us to be strict on the filters returned by the FilterBuilder.
type EntityFilter interface {
datastore.EntityFilter
}

type cloudFilterBuilder struct{}

func (b cloudFilterBuilder) PropertyFilter(FieldName string, Operator string, Value interface{}) EntityFilter {
return datastore.PropertyFilter{FieldName: FieldName, Operator: Operator, Value: Value}
}
35 changes: 21 additions & 14 deletions shared/test_run_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,14 @@ func (t testRunQueryImpl) LoadTestRunKeys(
log := GetLogger(t.store.Context())
result = make(KeysByProduct, len(products))
baseQuery := t.store.NewQuery("TestRun")
filterBuilder := baseQuery.FilterBuilder()
if offset != nil {
baseQuery = baseQuery.Offset(*offset)
}
if labels != nil {
labels.Remove("") // Ensure the empty string isn't present.
for i := range labels.Iter() {
baseQuery = baseQuery.Filter("Labels =", i.(string))
baseQuery = baseQuery.FilterEntity(filterBuilder.PropertyFilter("Labels", "=", i.(string)))
}
}
var globalIDFilter mapset.Set
Expand All @@ -143,10 +144,10 @@ func (t testRunQueryImpl) LoadTestRunKeys(

for i, product := range products {
var productIDFilter = merge(globalIDFilter, nil)
query := baseQuery.Filter("BrowserName =", product.BrowserName)
query := baseQuery.FilterEntity(filterBuilder.PropertyFilter("BrowserName", "=", product.BrowserName))
if product.Labels != nil {
for i := range product.Labels.Iter() {
query = query.Filter("Labels =", i.(string))
query = query.FilterEntity(filterBuilder.PropertyFilter("Labels", "=", i.(string)))
}
}
if !IsLatest(product.Revision) {
Expand Down Expand Up @@ -180,10 +181,10 @@ func (t testRunQueryImpl) LoadTestRunKeys(
// TODO(lukebjerring): Indexes + filtering for OS + version.
query = query.Order("-TimeStart")
if from != nil {
query = query.Filter("TimeStart >=", *from)
query = query.FilterEntity(filterBuilder.PropertyFilter("TimeStart", ">=", *from))
}
if to != nil {
query = query.Filter("TimeStart <", *to)
query = query.FilterEntity(filterBuilder.PropertyFilter("TimeStart", "<", *to))
}
max := MaxCountMaxValue
if limit != nil && *limit < MaxCountMaxValue {
Expand Down Expand Up @@ -267,17 +268,18 @@ func (t testRunQueryImpl) GetAlignedRunSHAs(
query := t.store.
NewQuery("TestRun").
Order("-TimeStart")
filterBuilder := query.FilterBuilder()

if labels != nil {
for i := range labels.Iter() {
query = query.Filter("Labels =", i.(string))
query = query.FilterEntity(filterBuilder.PropertyFilter("Labels", "=", i.(string)))
}
}
if from != nil {
query = query.Filter("TimeStart >=", *from)
query = query.FilterEntity(filterBuilder.PropertyFilter("TimeStart", ">=", *from))
}
if to != nil {
query = query.Filter("TimeStart <", *to)
query = query.FilterEntity(filterBuilder.PropertyFilter("TimeStart", "<", *to))
}

productsBySHA := make(map[string]mapset.Set)
Expand Down Expand Up @@ -356,16 +358,17 @@ func contains(s []string, x string) bool {
func loadIDsForRevision(store Datastore, query Query, sha string) (result mapset.Set, err error) {
log := GetLogger(store.Context())
var revQuery Query
filterBuilder := query.FilterBuilder()
if len(sha) < 40 {
log.Debugf("Finding revisions %s <= SHA < %s", sha, sha+"g")
revQuery = query.
Order("FullRevisionHash").
Limit(MaxCountMaxValue).
Filter("FullRevisionHash >=", sha).
Filter("FullRevisionHash <", sha+"g") // g > f
FilterEntity(filterBuilder.PropertyFilter("FullRevisionHash", ">=", sha)).
FilterEntity(filterBuilder.PropertyFilter("FullRevisionHash", "<", sha+"g")) // g > f
} else {
log.Debugf("Finding exact revision %s", sha)
revQuery = query.Filter("FullRevisionHash =", sha[:40])
revQuery = query.FilterEntity(filterBuilder.PropertyFilter("FullRevisionHash", "=", sha[:40]))
}

var keys []Key
Expand Down Expand Up @@ -393,7 +396,8 @@ func loadIDsForBrowserVersion(store Datastore, query Query, version string) (res
result.Add(id)
}
// By exact match
if keys, err = store.GetAll(query.Filter("BrowserVersion =", version).KeysOnly(), nil); err != nil {
if keys, err = store.GetAll(query.FilterEntity(
query.FilterBuilder().PropertyFilter("BrowserVersion", "=", version)).KeysOnly(), nil); err != nil {
return nil, err
}
for _, id := range GetTestRunIDs(keys) {
Expand All @@ -409,11 +413,14 @@ func VersionPrefix(query Query, fieldName, versionPrefix string, desc bool) Quer
if desc {
order = "-" + order
}
filterBuilder := query.FilterBuilder()
return query.
Limit(MaxCountMaxValue).
Order(order).
Filter(fieldName+" >=", fmt.Sprintf("%s.", versionPrefix)).
Filter(fieldName+" <=", fmt.Sprintf("%s.%c", versionPrefix, '9'+1))
FilterEntity(
filterBuilder.PropertyFilter(fieldName, ">=", fmt.Sprintf("%s.", versionPrefix))).
FilterEntity(
filterBuilder.PropertyFilter(fieldName, "<=", fmt.Sprintf("%s.%c", versionPrefix, '9'+1)))
}

func getTestRunRedisKey(id int64) string {
Expand Down
Loading