package orm import ( "errors" "fmt" "log" "net/http" "time" "github.com/jinzhu/gorm" "gogs.carduccidante.edu.it/karmen/core/generator" "gogs.carduccidante.edu.it/karmen/core/renderer" ) type GeneratorType struct { gorm.Model Name string } func (g *GeneratorType) String() string { return g.Name } type Document struct { gorm.Model Name string OutputPath string CloudPath string GeneratorTypeID uint `schema:"generator_type_id"` GeneratorType *GeneratorType KeepArtifacts bool Jobs []*Job RunningJobs []*Job CompletedJobs []*Job LastJob *Job `gorm:"-"` AllGeneratorTypes []*GeneratorType SelectedGeneratorType map[uint]string `gorm:"-"` } func (s *Document) GetID() uint { return s.ID } func (d *Document) String() string { return d.Name } func (d *Document) Create(args map[string]string, r *http.Request) (interface{}, error) { if r.Method == "GET" { document := new(Document) if err := DB().Find(&document.AllGeneratorTypes).Error; err != nil { return nil, err } return document, nil } else { document := new(Document) err := renderer.Decode(document, r) if err != nil { return nil, err } document, err = CreateDocument(document) if err != nil { return nil, err } return document, nil } } func (d *Document) Read(args map[string]string, r *http.Request) (interface{}, error) { var document Document id := args["id"] if err := DB().Preload("RunningJobs", "end = ?", time.Time{}).Where("id = ?", id).Find(&document).Error; err != nil { return nil, err } if err := DB().Preload("CompletedJobs", func(db *gorm.DB) *gorm.DB { return db.Where("end <> ?", time.Time{}).Limit(5).Order("end DESC") }).Where("id = ?", id).Find(&document).Error; err != nil { return nil, err } return &document, nil } func (d *Document) ReadAll(args map[string]string, r *http.Request) (interface{}, error) { var documents []*Document if err := DB().Preload("GeneratorType").Order("name").Find(&documents).Error; err != nil { return nil, err } return documents, nil } func (d *Document) Update(args map[string]string, r *http.Request) (interface{}, error) { if r.Method == "GET" { result, err := d.Read(args, r) if err != nil { return nil, err } document := result.(*Document) if err := DB().Find(&document.AllGeneratorTypes).Error; err != nil { return nil, err } document.SelectedGeneratorType = make(map[uint]string) document.SelectedGeneratorType[document.GeneratorTypeID] = "selected" return document, nil } else { document, err := d.Read(args, r) if err != nil { return nil, err } // FIXME: Should not be hard set. document.(*Document).KeepArtifacts = false err = renderer.Decode(document, r) if err != nil { return nil, err } _, err = SaveDocument(document) if err != nil { return nil, err } document, err = d.Read(args, r) if err != nil { return nil, err } return document.(*Document), nil } } func (d *Document) Delete(args map[string]string, r *http.Request) (interface{}, error) { document, err := d.Read(args, r) if err != nil { return nil, err } if err := DB().Unscoped().Delete(document.(*Document)).Error; err != nil { return nil, err } return document.(*Document), nil } func SaveDocument(document interface{}) (interface{}, error) { if err := DB().Save(document).Error; err != nil { return nil, err } return document, nil } func CreateDocument(document *Document) (*Document, error) { if err := DB().Create(document).Error; err != nil { return nil, err } return document, nil } func GetDocumentExecute(args map[string]string, r *http.Request) (interface{}, error) { var document Document if err := DB().Preload("GeneratorType").First(&document, args["id"]).Error; err != nil { return nil, err } // Create a new job job := new(Job) job.DocumentID = document.ID err := DB().Create(job).Error if err != nil { return nil, err } document.LastJob = job log.Printf("Start concurrent job %d for generator %s", job.ID, document.Name) if document.GeneratorType != nil { gen, ok := generator.Generators[document.GeneratorType.Name] if !ok { return nil, fmt.Errorf("Generator type %s not found!", document.GeneratorType.Name) } gen.SetJobId(job.ID) go gen.Run() } else { return nil, errors.New("Generator type not defined!") } return &document, nil }