func (a *Advisory) APIRequest(user *models.User, action string, value string) (interface{}, error) { if a.Ready { return nil, ErrAdvisoryAlreadyReady } switch action { case "type": a.Type = value a.model.ParentList().AddActivity(user, fmt.Sprintf("[Advisory] switched type to %v", value)) case "summary": a.Summary = value a.model.ParentList().AddActivity(user, fmt.Sprintf("[Advisory] switched summary to %v", value)) case "description": a.Description = value a.model.ParentList().AddActivity(user, fmt.Sprintf("[Advisory] switched description to %v", value)) case "existingAdv": a.ExistingAdvisoryID = uint(to.Uint64(value)) if a.ExistingAdvisoryID == 0 { a.model.ParentList().AddActivity(user, "[Advisory] detached from existing advisory") } else { a.model.ParentList().AddActivity(user, fmt.Sprintf("[Advisory] attached to existing advisory %v", a.ExistingAdvisoryID)) } case "ready": if a.ExistingAdvisoryID != 0 { a.Ready = true } else { if a.Type == "" || a.Summary == "" || a.Description == "" { return nil, ErrAdvisoryNotReady } } a.model.ParentList().AddActivity(user, "[Advisory] marked ready") default: return nil, ErrAdvisoryNoAction } if err := a.save(); err != nil { return nil, err } return map[string]interface{}{ "success": true, }, nil }
// Accept tells ABF to publish the build lists specified in the List. func (a *ABF) Accept(m *models.List) error { for _, v := range strings.Split(m.IntegrationOne, ";") { noBrackets := v[1 : len(v)-1] id := to.Uint64(noBrackets) req, err := http.NewRequest("PUT", abfURL+"/api/v1/build_lists/"+to.String(id)+"/publish.json", nil) if err != nil { return err } req.SetBasicAuth(abfUser, abfAPIKey) req.Header.Add("Content-Length", "0") resp, err := abfClient.Do(req) if err != nil { return err } defer resp.Body.Close() } return nil }
// BuildGetHandler displays build information for a specific build func BuildGetHandler(ctx context.Context, rw http.ResponseWriter, r *http.Request) { dataRenderer := data.FromContext(ctx) toRender := map[string]interface{}{} id := to.Uint64(pat.Param(ctx, "id")) var pkg models.List if err := models.DB.Where("id = ?", id).First(&pkg).Error; err != nil { if err == gorm.ErrRecordNotFound { panic(ErrNotFound) } else { panic(err) } } toRender["Title"] = "Build " + to.String(id) + ": " + pkg.Name toRender["Nav"] = 2 toRender["ID"] = to.String(id) dataRenderer.Data = toRender dataRenderer.Template = "builds/build" }
// Tests datatype conversions. func TestDataTypes(t *testing.T) { var res db.Result var items []db.Item sess, err := db.Open(wrapperName, settings) if err != nil { t.Fatalf(err.Error()) } defer sess.Close() dataTypes := sess.ExistentCollection("data_types") dataTypes.Truncate() ids, err := dataTypes.Append(testValues) if err != nil { t.Fatalf(err.Error()) } found, err := dataTypes.Count(db.Cond{"id": db.Id(ids[0])}) if err != nil { t.Fatalf(err.Error()) } if found == 0 { t.Errorf("Expecting an item.") } // Getting and reinserting (a db.Item). item, _ := dataTypes.Find() _, err = dataTypes.Append(item) if err == nil { t.Fatalf("Expecting duplicated-key error.") } delete(item, "id") _, err = dataTypes.Append(item) if err != nil { t.Fatalf(err.Error()) } // Testing date ranges items, err = dataTypes.FindAll(db.Cond{ "_date": time.Now(), }) if err != nil { t.Fatalf(err.Error()) } if len(items) > 0 { t.Fatalf("Expecting no results.") } items, err = dataTypes.FindAll(db.Cond{ "_date <=": time.Now(), }) if err != nil { t.Fatalf(err.Error()) } if len(items) != 2 { t.Fatalf("Expecting some results.") } // Testing struct sresults := []testValuesStruct{} res, err = dataTypes.Query() if err != nil { t.Fatalf(err.Error()) } err = res.All(&sresults) if err != nil { t.Fatalf(err.Error()) } // Testing struct equality for _, item := range sresults { if reflect.DeepEqual(item, testValues) == false { t.Errorf("Struct is different.") } } // Testing maps results, _ := dataTypes.FindAll() for _, item := range results { for key, _ := range item { switch key { // Signed integers. case "_int", "_int8", "_int16", "_int32", "_int64": if to.Int64(item[key]) != testValues.Int64 { t.Fatalf("Wrong datatype %v.", key) } // Unsigned integers. case "_uint", "_uint8", "_uint16", "_uint32", "_uint64": if to.Uint64(item[key]) != testValues.Uint64 { t.Fatalf("Wrong datatype %v.", key) } // Floating point. case "_float32": case "_float64": if to.Float64(item[key]) != testValues.Float64 { t.Fatalf("Wrong datatype %v.", key) } // Boolean case "_bool": if to.Bool(item[key]) != testValues.Bool { t.Fatalf("Wrong datatype %v.", key) } // String case "_string": if to.String(item[key]) != testValues.String { t.Fatalf("Wrong datatype %v.", key) } // Date case "_date": if to.Time(item[key]).Equal(testValues.Date) == false { t.Fatalf("Wrong datatype %v.", key) } } } } }
// BuildPostHandler handles post actions that occur to the current active stage. func BuildPostHandler(ctx context.Context, rw http.ResponseWriter, r *http.Request) { // check for authentication user := models.FindUser(MustAuthenticate(r)) // setup dataRenderer := data.FromContext(ctx) // read parameters id := to.Uint64(pat.Param(ctx, "id")) target := r.FormValue("target") // either activity or process name := r.FormValue("name") // activity (ignored), process - find process action := r.FormValue("action") // activity (ignored), process passed on value := r.FormValue("value") // activity (comment), process passed on // find the build list var pkg models.List if err := models.DB.Where("id = ?", id).First(&pkg).Related(&pkg.Stages, "Stages").Error; err != nil { if err == gorm.ErrRecordNotFound { panic(ErrNotFound) } else { panic(err) } } var result interface{} // act based on target switch target { case "activity": if value == "" { panic(ErrBadRequest) } pkg.AddActivity(user, value) result = map[string]interface{}{ "success": true, } case "process": // load up the stage & process if err := models.DB.Related(&pkg.Stages, "Stages").Error; err != nil { panic(err) } var currentStage *models.ListStage for _, v := range pkg.Stages { if v.Name == pkg.StageCurrent { currentStage = &v break } } if currentStage == nil { panic(ErrNoCurrentStage) } if err := models.DB.Related(¤tStage.Processes).Error; err != nil { panic(err) } var selectedProcess *models.ListStageProcess for _, v := range currentStage.Processes { if v.Name == name { selectedProcess = &v break } } if selectedProcess == nil { panic(ErrBadRequest) } // initialise the process process, err := processes.BuildProcess(selectedProcess) if err != nil { panic(err) } r, err := process.APIRequest(user, action, value) if err != nil { result = map[string]interface{}{ "error": true, "message": err.Error(), "result": r, } } else { result = r } default: panic(ErrBadRequest) } dataRenderer.Type = data.DataJSON dataRenderer.Data = result //http.Redirect(rw, r, r.URL.String(), http.StatusTemporaryRedirect) }
// BuildGetJSONHandler displays build information in JSON for a specific build. func BuildGetJSONHandler(ctx context.Context, rw http.ResponseWriter, r *http.Request) { dataRenderer := data.FromContext(ctx) id := to.Uint64(pat.Param(ctx, "id")) user := models.FindUserNoCreate(Authenticated(r)) // load the requested build list var pkg models.List if err := models.DB.Where("id = ?", id).First(&pkg).Related(&pkg.Activity, "Activity").Related(&pkg.Artifacts, "Artifacts").Related(&pkg.Links, "Links").Related(&pkg.Stages, "Stages").Error; err != nil { if err == gorm.ErrRecordNotFound { panic(ErrNotFound) } else { panic(err) } } // load stage information var stageInfo []buildGetJSONStage for _, v := range pkg.Stages { if err := models.DB.Related(&v.Processes, "Processes").Error; err != nil && err != gorm.ErrRecordNotFound { panic(err) } // get all process info status := map[string]processes.ProcessStatus{} metadata := map[string]interface{}{} optional := map[string]bool{} for _, p := range v.Processes { process, err := processes.BuildProcess(&p) if err != nil { panic(err) } status[p.Name] = process.Status() metadata[p.Name] = process.APIMetadata(user) optional[p.Name] = p.Optional } stageInfo = append(stageInfo, buildGetJSONStage{ Name: v.Name, Status: status, Metadata: metadata, Optional: optional, }) } // render the data in a nice way dataRenderer.Data = &buildGetJSON{ ID: pkg.ID, Platform: pkg.Platform, Channel: pkg.Channel, Variants: strings.Split(pkg.Variants, ";"), Name: pkg.Name, Artifacts: pkg.Artifacts, Links: pkg.Links, Activity: pkg.Activity, Changes: pkg.Changes, BuildDate: pkg.BuildDate, Updated: pkg.UpdatedAt, PlatformConfig: pkg.PlatformGitConfig, Stages: stageInfo, CurrentStage: pkg.StageCurrent, Status: pkg.StageResult, Advisory: pkg.AdvisoryID, } dataRenderer.Type = data.DataJSON }
// Appends an item (map or struct) into the collection. func (t *table) Append(item interface{}) (interface{}, error) { var pKey []string var columns sqlgen.Columns var values sqlgen.Values var arguments []interface{} //var id []interface{} cols, vals, err := t.FieldValues(item, toInternal) if err != nil { return nil, err } columns = make(sqlgen.Columns, 0, len(cols)) for i := range cols { columns = append(columns, sqlgen.Column{cols[i]}) } arguments = make([]interface{}, 0, len(vals)) values = make(sqlgen.Values, 0, len(vals)) for i := range vals { switch v := vals[i].(type) { case sqlgen.Value: // Adding value. values = append(values, v) default: // Adding both value and placeholder. values = append(values, sqlPlaceholder) arguments = append(arguments, v) } } if pKey, err = t.source.getPrimaryKey(t.tableN(0)); err != nil { if err != sql.ErrNoRows { // Can't tell primary key. return nil, err } } stmt := sqlgen.Statement{ Type: sqlgen.SqlInsert, Table: sqlgen.Table{t.tableN(0)}, Columns: columns, Values: values, } // No primary keys defined. if len(pKey) == 0 { var res sql.Result if res, err = t.source.doExec(stmt, arguments...); err != nil { return nil, err } // Attempt to use LastInsertId() (probably won't work, but the exec() // succeeded, so the error from LastInsertId() is ignored). lastID, _ := res.LastInsertId() return lastID, nil } var rows *sql.Rows // A primary key was found. stmt.Extra = sqlgen.Extra(fmt.Sprintf(`RETURNING "%s"`, strings.Join(pKey, `", "`))) if rows, err = t.source.doQuery(stmt, arguments...); err != nil { return nil, err } defer rows.Close() var keyMap map[string]interface{} err = sqlutil.FetchRow(rows, &keyMap) // Does the item satisfy the db.IDSetter interface? if setter, ok := item.(db.IDSetter); ok { if err := setter.SetID(keyMap); err != nil { return nil, err } return nil, nil } // The IDSetter interface does not match, we'll be looking for another // interface match. if len(keyMap) == 1 { id := keyMap[pKey[0]] // Matches db.Int64IDSetter if setter, ok := item.(db.Int64IDSetter); ok { if err = setter.SetID(to.Int64(id)); err != nil { return nil, err } return nil, nil } // Matches db.Uint64IDSetter if setter, ok := item.(db.Uint64IDSetter); ok { if err = setter.SetID(to.Uint64(id)); err != nil { return nil, err } return nil, nil } // No interface matched, falling back to old behaviour. return to.Int64(id), nil } // More than one key, no interface matched, let's return a map. return keyMap, nil }