package changes import ( "log" "strconv" "time" "git.aiterp.net/rpdata/api/internal/counter" "git.aiterp.net/rpdata/api/models" ) // Submit a change to the database. The objects may be any supported model, or arrays. func Submit(model, op, author string, listed bool, keys []models.ChangeKey, objects ...interface{}) (models.Change, error) { submitMutex.Lock() defer submitMutex.Unlock() id, err := counter.Next("auto_increment", "Change") if err != nil { return models.Change{}, err } if !models.ChangeModel(model).IsValid() { panic("Invalid model") } // Silently discard * keys on unlisted changes. if !listed { keysCopy := make([]models.ChangeKey, len(keys)) copy(keysCopy, keys) keys = keysCopy deletes := make([]int, 0, 1) for i, key := range keys { if key.ID == "*" { deletes = append(deletes, i-len(deletes)) } } for _, index := range deletes { keys = append(keys[:index], keys[index+1:]...) } } change := models.Change{ ID: "Change_" + strconv.Itoa(id), Model: models.ChangeModel(model), Date: time.Now(), Op: op, Author: author, Keys: keys, Listed: listed, } for _, object := range objects { switch object := object.(type) { case models.Log: change.Logs = append(change.Logs, object) case *models.Log: change.Logs = append(change.Logs, *object) case []models.Log: change.Logs = append(change.Logs, object...) case models.Character: change.Characters = append(change.Characters, object) case *models.Character: change.Characters = append(change.Characters, *object) case []models.Character: change.Characters = append(change.Characters, object...) case models.Channel: change.Channels = append(change.Channels, object) case *models.Channel: change.Channels = append(change.Channels, *object) case []models.Channel: change.Channels = append(change.Channels, object...) case models.Post: change.Posts = append(change.Posts, object) case *models.Post: change.Posts = append(change.Posts, *object) case []models.Post: change.Posts = append(change.Posts, object...) case models.Story: change.Stories = append(change.Stories, object) case *models.Story: change.Stories = append(change.Stories, *object) case []models.Story: change.Stories = append(change.Stories, object...) case models.Tag: change.Tags = append(change.Tags, object) case *models.Tag: change.Tags = append(change.Tags, *object) case []models.Tag: change.Tags = append(change.Tags, object...) case models.Chapter: change.Chapters = append(change.Chapters, object) case *models.Chapter: change.Chapters = append(change.Chapters, *object) case []models.Chapter: change.Chapters = append(change.Chapters, object...) case models.Comment: change.Comments = append(change.Comments, object) case *models.Comment: change.Comments = append(change.Comments, *object) case []models.Comment: change.Comments = append(change.Comments, object...) default: log.Printf("Warning: unrecognized object in change: %#+v", object) } } pushToSubscribers(change) err = collection.Insert(&change) if err != nil { return models.Change{}, err } return change, nil }