github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/model/build/db.go (about)

     1  package build
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/evergreen-ci/evergreen"
     7  	"github.com/evergreen-ci/evergreen/db"
     8  	"github.com/evergreen-ci/evergreen/db/bsonutil"
     9  	"gopkg.in/mgo.v2"
    10  	"gopkg.in/mgo.v2/bson"
    11  )
    12  
    13  // The MongoDB collection for build documents.
    14  const Collection = "builds"
    15  
    16  var (
    17  	// bson fields for the build struct
    18  	IdKey                  = bsonutil.MustHaveTag(Build{}, "Id")
    19  	CreateTimeKey          = bsonutil.MustHaveTag(Build{}, "CreateTime")
    20  	StartTimeKey           = bsonutil.MustHaveTag(Build{}, "StartTime")
    21  	FinishTimeKey          = bsonutil.MustHaveTag(Build{}, "FinishTime")
    22  	PushTimeKey            = bsonutil.MustHaveTag(Build{}, "PushTime")
    23  	VersionKey             = bsonutil.MustHaveTag(Build{}, "Version")
    24  	ProjectKey             = bsonutil.MustHaveTag(Build{}, "Project")
    25  	RevisionKey            = bsonutil.MustHaveTag(Build{}, "Revision")
    26  	BuildVariantKey        = bsonutil.MustHaveTag(Build{}, "BuildVariant")
    27  	BuildNumberKey         = bsonutil.MustHaveTag(Build{}, "BuildNumber")
    28  	StatusKey              = bsonutil.MustHaveTag(Build{}, "Status")
    29  	ActivatedKey           = bsonutil.MustHaveTag(Build{}, "Activated")
    30  	ActivatedByKey         = bsonutil.MustHaveTag(Build{}, "ActivatedBy")
    31  	ActivatedTimeKey       = bsonutil.MustHaveTag(Build{}, "ActivatedTime")
    32  	RevisionOrderNumberKey = bsonutil.MustHaveTag(Build{}, "RevisionOrderNumber")
    33  	TasksKey               = bsonutil.MustHaveTag(Build{}, "Tasks")
    34  	TimeTakenKey           = bsonutil.MustHaveTag(Build{}, "TimeTaken")
    35  	DisplayNameKey         = bsonutil.MustHaveTag(Build{}, "DisplayName")
    36  	RequesterKey           = bsonutil.MustHaveTag(Build{}, "Requester")
    37  	PredictedMakespanKey   = bsonutil.MustHaveTag(Build{}, "PredictedMakespan")
    38  	ActualMakespanKey      = bsonutil.MustHaveTag(Build{}, "ActualMakespan")
    39  
    40  	// bson fields for the task caches
    41  	TaskCacheIdKey            = bsonutil.MustHaveTag(TaskCache{}, "Id")
    42  	TaskCacheDisplayNameKey   = bsonutil.MustHaveTag(TaskCache{}, "DisplayName")
    43  	TaskCacheStatusKey        = bsonutil.MustHaveTag(TaskCache{}, "Status")
    44  	TaskCacheStatusDetailsKey = bsonutil.MustHaveTag(TaskCache{}, "StatusDetails")
    45  	TaskCacheStartTimeKey     = bsonutil.MustHaveTag(TaskCache{}, "StartTime")
    46  	TaskCacheTimeTakenKey     = bsonutil.MustHaveTag(TaskCache{}, "TimeTaken")
    47  	TaskCacheActivatedKey     = bsonutil.MustHaveTag(TaskCache{}, "Activated")
    48  )
    49  
    50  // Queries
    51  
    52  // All returns all builds.
    53  var All = db.Query(nil)
    54  
    55  // ById creates a query that finds a build by its _id.
    56  func ById(id string) db.Q {
    57  	return db.Query(bson.D{{IdKey, id}})
    58  }
    59  
    60  // ByIds creates a query that finds all builds with the given ids.
    61  func ByIds(ids []string) db.Q {
    62  	return db.Query(bson.D{{IdKey, bson.D{{"$in", ids}}}})
    63  }
    64  
    65  // ByVersion creates a query that returns all builds for a given version.
    66  func ByVersion(version string) db.Q {
    67  	return db.Query(bson.D{{VersionKey, version}})
    68  }
    69  
    70  // ByVersions creates a query that finds all builds with the given version ids.
    71  func ByVersions(vIds []string) db.Q {
    72  	return db.Query(bson.D{{VersionKey, bson.D{{"$in", vIds}}}})
    73  }
    74  
    75  // ByVariant creates a query that finds all builds for a given variant.
    76  func ByVariant(bv string) db.Q {
    77  	return db.Query(bson.D{{BuildVariantKey, bv}})
    78  }
    79  
    80  // ByProject creates a query that finds all builds for a given project id.
    81  func ByProject(proj string) db.Q {
    82  	return db.Query(bson.D{{ProjectKey, proj}})
    83  }
    84  
    85  // ByProjectAndVariant creates a query that finds all completed builds for a given project
    86  // and variant, while also specifying a requester
    87  func ByProjectAndVariant(project, variant, requester string) db.Q {
    88  	return db.Query(bson.M{
    89  		ProjectKey:      project,
    90  		StatusKey:       bson.M{"$in": evergreen.CompletedStatuses},
    91  		BuildVariantKey: variant,
    92  		RequesterKey:    requester,
    93  	})
    94  }
    95  
    96  // ByRevisionAndVariant creates a query that returns the non-patch build for
    97  // a revision + buildvariant combionation.
    98  func ByRevisionAndVariant(revision, variant string) db.Q {
    99  	return db.Query(bson.M{
   100  		RevisionKey:     revision,
   101  		RequesterKey:    evergreen.RepotrackerVersionRequester,
   102  		BuildVariantKey: variant,
   103  	})
   104  }
   105  
   106  // ByRevision creates a query that returns all builds for a revision.
   107  func ByRevision(revision string) db.Q {
   108  	return db.Query(bson.M{
   109  		RevisionKey:  revision,
   110  		RequesterKey: evergreen.RepotrackerVersionRequester,
   111  	})
   112  }
   113  
   114  // ByRecentlyActivatedForProjectAndVariant builds a query that returns all
   115  // builds before a given revision that were activated for a project + variant.
   116  // Builds are sorted from most to least recent.
   117  func ByRecentlyActivatedForProjectAndVariant(revision int, project, variant, requester string) db.Q {
   118  	return db.Query(bson.M{
   119  		RevisionOrderNumberKey: bson.M{"$lt": revision},
   120  		ActivatedKey:           true,
   121  		BuildVariantKey:        variant,
   122  		ProjectKey:             project,
   123  		RequesterKey:           requester,
   124  	}).Sort([]string{"-" + RevisionOrderNumberKey})
   125  }
   126  
   127  // ByRecentlySuccessfulForProjectAndVariant builds a query that returns all
   128  // builds before a given revision that were successful for a project + variant.
   129  // Builds are sorted from most to least recent.
   130  func ByRecentlySuccessfulForProjectAndVariant(revision int, project, variant string) db.Q {
   131  	return db.Query(bson.M{
   132  		RevisionOrderNumberKey: bson.M{"$lt": revision},
   133  		BuildVariantKey:        variant,
   134  		ProjectKey:             project,
   135  		StatusKey:              evergreen.BuildSucceeded,
   136  		RequesterKey:           evergreen.RepotrackerVersionRequester,
   137  	}).Sort([]string{"-" + RevisionOrderNumberKey})
   138  }
   139  
   140  // ByFinishedAfter creates a query that returns all builds for a project/requester
   141  // that were finished after the given time.
   142  func ByFinishedAfter(finishTime time.Time, project string, requester string) db.Q {
   143  	query := bson.M{
   144  		TimeTakenKey:  bson.M{"$ne": time.Duration(0)},
   145  		FinishTimeKey: bson.M{"$gt": finishTime},
   146  		RequesterKey:  requester,
   147  	}
   148  	// filter by project, optionally
   149  	if project != "" {
   150  		query[ProjectKey] = project
   151  	}
   152  	return db.Query(query)
   153  }
   154  
   155  // ByBetweenBuilds returns all builds that happened between
   156  // the current and previous build.
   157  func ByBetweenBuilds(current, previous *Build) db.Q {
   158  	intermediateRevisions := bson.M{
   159  		"$lt": current.RevisionOrderNumber,
   160  		"$gt": previous.RevisionOrderNumber,
   161  	}
   162  	q := db.Query(bson.M{
   163  		BuildVariantKey:        current.BuildVariant,
   164  		RequesterKey:           current.Requester,
   165  		RevisionOrderNumberKey: intermediateRevisions,
   166  		ProjectKey:             current.Project,
   167  	}).Sort([]string{RevisionOrderNumberKey})
   168  	return q
   169  }
   170  
   171  // ByBeforeRevision builds a query that returns all builds
   172  // that happened before the given revision for the project/variant.
   173  // Results are sorted by revision order, descending.
   174  func ByBeforeRevision(project, buildVariant string, revision int) db.Q {
   175  	return db.Query(bson.M{
   176  		ProjectKey:             project,
   177  		BuildVariantKey:        buildVariant,
   178  		RequesterKey:           evergreen.RepotrackerVersionRequester,
   179  		RevisionOrderNumberKey: bson.M{"$lt": revision},
   180  	}).Sort([]string{"-" + RevisionOrderNumberKey})
   181  }
   182  
   183  // ByAfterRevision builds a query that returns all builds
   184  // that happened at or after the given revision for the project/variant.
   185  // Results are sorted by revision order, ascending.
   186  func ByAfterRevision(project, buildVariant string, revision int) db.Q {
   187  	return db.Query(bson.M{
   188  		ProjectKey:             project,
   189  		BuildVariantKey:        buildVariant,
   190  		RequesterKey:           evergreen.RepotrackerVersionRequester,
   191  		RevisionOrderNumberKey: bson.M{"$gte": revision},
   192  	}).Sort([]string{RevisionOrderNumberKey})
   193  }
   194  
   195  // ByRecentlyFinished builds a query that returns all builds for a given project
   196  // that are versions (not patches), that have finished.
   197  func ByRecentlyFinished(limit int) db.Q {
   198  	return db.Query(bson.M{
   199  		RequesterKey: evergreen.RepotrackerVersionRequester,
   200  		StatusKey:    bson.M{"$in": evergreen.CompletedStatuses},
   201  	}).Sort([]string{RevisionOrderNumberKey}).Limit(limit)
   202  }
   203  
   204  // DB Boilerplate
   205  
   206  // FindOne returns one build that satisfies the query.
   207  func FindOne(query db.Q) (*Build, error) {
   208  	build := &Build{}
   209  	err := db.FindOneQ(Collection, query, build)
   210  	if err == mgo.ErrNotFound {
   211  		return nil, nil
   212  	}
   213  	return build, err
   214  }
   215  
   216  // Find returns all builds that satisfy the query.
   217  func Find(query db.Q) ([]Build, error) {
   218  	builds := []Build{}
   219  	err := db.FindAllQ(Collection, query, &builds)
   220  	if err == mgo.ErrNotFound {
   221  		return nil, nil
   222  	}
   223  	return builds, err
   224  }
   225  
   226  // UpdateOne updates one build.
   227  func UpdateOne(query interface{}, update interface{}) error {
   228  	return db.Update(
   229  		Collection,
   230  		query,
   231  		update,
   232  	)
   233  }
   234  
   235  func UpdateAllBuilds(query interface{}, update interface{}) (*mgo.ChangeInfo, error) {
   236  	return db.UpdateAll(
   237  		Collection,
   238  		query,
   239  		update,
   240  	)
   241  }
   242  
   243  // Remove deletes the build of the given id from the database
   244  func Remove(id string) error {
   245  	return db.Remove(
   246  		Collection,
   247  		bson.M{IdKey: id},
   248  	)
   249  }