Ejemplo n.º 1
0
func FindModel(model models.Model, db *pgx.ConnPool, tx *pgx.Tx, where string, fields ...string) error {
	fieldNames, fieldValues := model.Fields(fields...)

	query := SqlSelect(model.TableName(), fieldNames)

	where = fmt.Sprintf(" WHERE %s = ? %s", model.PrimaryName(), where)

	query = FormateToPQuery(query + where)
	args := []interface{}{model.PrimaryValue()}

	var err error

	if tx != nil {
		err = tx.QueryRow(query, args...).Scan(fieldValues...)
	} else {
		err = db.QueryRow(query, args...).Scan(fieldValues...)
	}

	if err == pgx.ErrNoRows {

		return models.ErrNotFound
	}

	if err != nil {

		return err
	}

	return nil
}
Ejemplo n.º 2
0
func (d *pgDataStore) addCertWithTx(tx *pgx.Tx, c *router.Certificate) error {
	c.Cert = strings.Trim(c.Cert, " \n")
	c.Key = strings.Trim(c.Key, " \n")

	if _, err := tls.X509KeyPair([]byte(c.Cert), []byte(c.Key)); err != nil {
		return httphelper.JSONError{
			Code:    httphelper.ValidationErrorCode,
			Message: "Certificate invalid: " + err.Error(),
		}
	}

	tlsCertSHA256 := sha256.Sum256([]byte(c.Cert))
	if err := tx.QueryRow("select_certificate_by_sha", tlsCertSHA256[:]).Scan(&c.ID, &c.CreatedAt, &c.UpdatedAt); err != nil {
		if err := tx.QueryRow("insert_certificate", c.Cert, c.Key, tlsCertSHA256[:]).Scan(&c.ID, &c.CreatedAt, &c.UpdatedAt); err != nil {
			return err
		}
	}
	for _, rid := range c.Routes {
		if _, err := tx.Exec("delete_route_certificate_by_route_id", rid); err != nil {
			return err
		}
		if _, err := tx.Exec("insert_route_certificate", rid, c.ID); err != nil {
			return err
		}
	}
	return nil
}
Ejemplo n.º 3
0
func fetchConfig(database *pgx.Tx, name string) (*Config, *requestError) {
	dbConfig := Config{Name: name}
	err := database.QueryRow("queryConfig", name).Scan(&dbConfig.MonoExecutable, &dbConfig.MonoEnvironmentVariables, &dbConfig.MonoOptions)
	if err == pgx.ErrNoRows {
		return nil, nil
	}
	if err != nil {
		return nil, internalServerError("Database query error")

	}
	return &dbConfig, nil
}
Ejemplo n.º 4
0
func insertRuns(database *pgx.Tx, runSetID int32, runs []Run) ([]int32, *requestError) {
	var runIDs []int32
	for _, run := range runs {
		var runID int32
		err := database.QueryRow("insertRun", run.Benchmark, runSetID).Scan(&runID)
		if err != nil {
			fmt.Printf("run insert error: %s\n", err)
			return nil, internalServerError("Could not insert run")
		}
		runIDs = append(runIDs, runID)

		reqErr := insertResults(database, runID, run.Results, false)
		if reqErr != nil {
			return nil, reqErr
		}
	}
	return runIDs, nil
}
Ejemplo n.º 5
0
func updateOrCreateModel(model models.Model, db *pgx.ConnPool, tx *pgx.Tx, isNew, isRemove bool, where string, fields ...string) error {
	if isNew {
		model.BeforeCreate()
	}

	if isRemove {
		model.BeforeDelete()
	}

	model.BeforeSave()

	fieldNames, fieldValues := model.Fields(fields...)

	var query string = SqlUpdate(model.TableName(), fieldNames)

	if isNew {
		query = SqlInsert(model.TableName(), fieldNames)
	}

	where = fmt.Sprintf(" WHERE %[1]s = ? %[2]s RETURNING %[1]s", model.PrimaryName(), where)
	if isNew {
		where = fmt.Sprintf(" RETURNING %s", model.PrimaryName())
	} else {
		fieldValues = append(fieldValues, model.PrimaryValue())
	}

	query = FormateToPQuery(query + where)

	var err error

	if tx != nil {
		err = tx.QueryRow(query, fieldValues...).Scan(model.Maps()[model.PrimaryName()])

	} else {
		err = db.QueryRow(query, fieldValues...).Scan(model.Maps()[model.PrimaryName()])
	}

	if err != nil {

		return err
	}

	return nil
}
Ejemplo n.º 6
0
func ensureProductExists(database *pgx.Tx, product Product) (string, *requestError) {
	var commitDate time.Time
	// FIXME: check and update mergeBaseHash
	err := database.QueryRow("queryCommitWithProduct", product.Commit, product.Name).Scan(&commitDate)
	if err == nil {
		return product.Commit, nil
	}

	if err == pgx.ErrNoRows {
		var sha string
		fmt.Printf("Commit %s for product %s not found in DB.\n", product.Commit, product.Name)

		owner, repo := githubRepoForProduct(product.Name)
		if owner == "" || repo == "" {
			return "", badRequestError("Unknown product")
		}

		commit, _, err := githubClient.Git.GetCommit(owner, repo, product.Commit)
		if err == nil {
			sha = *commit.SHA
			commitDate = *commit.Committer.Date
		} else {
			// try to fall back to provided commitDate
			if product.CommitDate != nil {
				sha = product.Commit
				commitDate = *product.CommitDate
			} else {
				return "", badRequestError("Could not get date for provided commit " + product.Commit)
			}
		}

		_, err = database.Exec("insertCommit", sha, commitDate, product.Name, product.MergeBaseHash)
		if err != nil {
			return "", internalServerError("Couldn't insert commit")
		}

		return sha, nil
	}

	return "", internalServerError("Database query error")
}
Ejemplo n.º 7
0
func ensureMachineExists(database *pgx.Tx, machine Machine) *requestError {
	var architecture string
	err := database.QueryRow("queryMachine", machine.Name).Scan(&architecture)
	if err == nil {
		if machine.Architecture != architecture {
			return badRequestError("Machine has a different architecture than the one in the database")
		}
		return nil
	}

	if err == pgx.ErrNoRows {
		_, err = database.Exec("insertMachine", machine.Name, machine.Architecture)
		if err != nil {
			return internalServerError("Could not insert machine")
		}

		return nil
	}

	return internalServerError("Database query error")
}
Ejemplo n.º 8
0
func fetchRunSet(database *pgx.Tx, id int32, withRuns bool) (*RunSet, *requestError) {
	var rs RunSet
	var secondaryCommits []string
	var pullRequestID *int32
	err := database.QueryRow("queryRunSet", id).Scan(&rs.StartedAt, &rs.FinishedAt,
		&rs.BuildURL, &rs.LogURLs,
		&rs.MainProduct.Commit, &secondaryCommits, &rs.Machine.Name, &rs.Config.Name,
		&rs.TimedOutBenchmarks, &rs.CrashedBenchmarks,
		&pullRequestID)
	if err == pgx.ErrNoRows {
		return nil, badRequestError("Run set does not exist")
	}
	if err != nil {
		fmt.Printf("run set query error: %s\n", err.Error())
		return nil, internalServerError("Could not get run set")
	}

	// FIXME: combine these two queries with the above one
	err = database.QueryRow("queryCommit", rs.MainProduct.Commit).Scan(&rs.MainProduct.Name)
	if err != nil {
		return nil, internalServerError("Could not get commit")
	}

	for _, c := range secondaryCommits {
		product := Product{Commit: c}
		err = database.QueryRow("queryCommit", c).Scan(&product.Name)
		if err != nil {
			return nil, internalServerError("Could not get commit")
		}

		rs.SecondaryProducts = append(rs.SecondaryProducts, product)
	}

	err = database.QueryRow("queryMachine", rs.Machine.Name).Scan(&rs.Machine.Architecture)
	if err != nil {
		return nil, internalServerError("Could not get machine")
	}

	config, reqErr := fetchConfig(database, rs.Config.Name)
	if reqErr != nil {
		return nil, nil
	}

	rs.Config = *config

	if withRuns {
		rows, err := database.Query("queryRunMetrics", id)
		if err != nil {
			return nil, internalServerError("Could not get run metrics")
		}
		defer rows.Close()

		runs := make(map[int32]*Run)

		for rows.Next() {
			var runID int32
			var benchmark string
			var metric string
			var resultNumber *float64
			var resultArray []float64

			if err = rows.Scan(&runID, &benchmark, &metric, &resultNumber, &resultArray); err != nil {
				return nil, internalServerError("Could not scan run metric: " + err.Error())
			}

			var resultValue interface{}
			if metricIsArray(metric) {
				resultValue = resultArray
			} else if resultNumber != nil {
				resultValue = *resultNumber
			} else {
				return nil, internalServerError("Run metric data is inconsistent")
			}

			run := runs[runID]
			if run == nil {
				run = &Run{Benchmark: benchmark, Results: make(map[string]interface{})}
				runs[runID] = run
			}

			run.Results[metric] = resultValue
		}

		for _, r := range runs {
			rs.Runs = append(rs.Runs, *r)
		}
	}

	return &rs, nil
}
Ejemplo n.º 9
0
func runSetPutHandler(database *pgx.Tx, w http.ResponseWriter, r *http.Request, body []byte) (bool, *requestError) {
	var params RunSet
	if err := json.Unmarshal(body, &params); err != nil {
		fmt.Printf("Unmarshal error: %s\n", err.Error())
		return false, badRequestError("Could not parse request body")
	}

	reqErr := ensureMachineExists(database, params.Machine)
	if reqErr != nil {
		return false, reqErr
	}

	mainCommit, reqErr := ensureProductExists(database, params.MainProduct)
	if reqErr != nil {
		return false, reqErr
	}

	var secondaryCommits []string
	for _, p := range params.SecondaryProducts {
		commit, reqErr := ensureProductExists(database, p)
		if reqErr != nil {
			return false, reqErr
		}
		secondaryCommits = append(secondaryCommits, commit)
	}

	reqErr = params.ensureBenchmarksAndMetricsExist(database)
	if reqErr != nil {
		return false, reqErr
	}

	reqErr = ensureConfigExists(database, params.Config)
	if reqErr != nil {
		return false, reqErr
	}

	var pullRequestID *int32
	if params.PullRequest != nil {
		var prID int32
		pullRequestID = &prID
		err := database.QueryRow("insertPullRequest",
			params.PullRequest.BaselineRunSetID,
			params.PullRequest.URL).Scan(pullRequestID)
		if err != nil {
			fmt.Printf("pull request insert error: %s\n", err)
			return false, internalServerError("Could not insert pull request")
		}
	}

	var runSetID int32
	err := database.QueryRow("insertRunSet",
		params.StartedAt, params.FinishedAt,
		params.BuildURL, params.LogURLs,
		mainCommit, secondaryCommits, params.Machine.Name, params.Config.Name,
		params.TimedOutBenchmarks, params.CrashedBenchmarks,
		pullRequestID).Scan(&runSetID)
	if err != nil {
		fmt.Printf("run set insert error: %s\n", err)
		return false, internalServerError("Could not insert run set")
	}

	runIDs, reqErr := insertRuns(database, runSetID, params.Runs)
	if reqErr != nil {
		return false, reqErr
	}

	resp := runsetPostResponse{RunSetID: runSetID, RunIDs: runIDs, PullRequestID: pullRequestID}
	respBytes, err := json.Marshal(&resp)
	if err != nil {
		return false, internalServerError("Could not produce JSON for response")
	}

	w.WriteHeader(http.StatusCreated)
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.Write(respBytes)

	return true, nil
}