|
|
package models
import ( "reflect" "time" )
// Change represents a change in the rpdata history through the API.
type Change struct { ID string `bson:"_id"` Model ChangeModel `bson:"model"` Op string `bson:"op"` Author string `bson:"author"` Listed bool `bson:"listed"` Keys []ChangeKey `bson:"keys"` Date time.Time `bson:"date"`
Logs []Log `bson:"logs"` Characters []Character `bson:"characters"` Channels []Channel `bson:"channels"` Posts []Post `bson:"posts"` Stories []Story `bson:"stories"` Tags []Tag `bson:"tags"` Chapters []Chapter `bson:"chapters"` Comments []Comment `bson:"comments"` }
// AddObject adds the model into the appropriate array.
func (change *Change) AddObject(object interface{}) bool { if v := reflect.ValueOf(object); v.Kind() == reflect.Ptr { return change.AddObject(v.Elem().Interface()) }
switch object := object.(type) { case Log: change.Logs = append(change.Logs, object) case []Log: change.Logs = append(change.Logs, object...) case Character: change.Characters = append(change.Characters, object) case []Character: change.Characters = append(change.Characters, object...) case Channel: change.Channels = append(change.Channels, object) case []Channel: change.Channels = append(change.Channels, object...) case Post: change.Posts = append(change.Posts, object) case []Post: change.Posts = append(change.Posts, object...) case Story: change.Stories = append(change.Stories, object) case []Story: change.Stories = append(change.Stories, object...) case Tag: change.Tags = append(change.Tags, object) case []Tag: change.Tags = append(change.Tags, object...) case Chapter: change.Chapters = append(change.Chapters, object) case []Chapter: change.Chapters = append(change.Chapters, object...) case Comment: change.Comments = append(change.Comments, object) case []Comment: change.Comments = append(change.Comments, object...) default: return false }
return true }
// Objects makes a combined, mixed array of all the models stored in this change.
func (change *Change) Objects() []interface{} { data := make([]interface{}, 0, 8)
for _, log := range change.Logs { data = append(data, &log) } for _, channel := range change.Channels { data = append(data, &channel) } for _, character := range change.Characters { data = append(data, &character) } for _, post := range change.Posts { data = append(data, &post) } for _, story := range change.Stories { data = append(data, &story) } for _, tag := range change.Tags { data = append(data, &tag) } for _, chapter := range change.Chapters { data = append(data, &chapter) } for _, comment := range change.Comments { data = append(data, &comment) }
return data }
func (change *Change) PassesFilter(filter ChangeFilter) bool { if filter.PassAll { return true }
if filter.Author != nil && change.Author != *filter.Author { return false }
// For unlisted changes, pass it only if the filter refers to the specific index.
if !change.Listed { hasSpecificKey := false
KeyFindLoop: for _, key := range filter.Keys { if key.ID == "*" { continue }
for _, changeKey := range change.Keys { if changeKey.Model == key.Model && changeKey.ID == key.ID { hasSpecificKey = true break KeyFindLoop } } }
if !hasSpecificKey { return false } }
if filter.EarliestDate != nil && filter.EarliestDate.Before(change.Date) { return false }
if len(filter.Keys) > 0 { foundKey := false
KeyFindLoop2: for _, key := range filter.Keys { for _, changeKey := range change.Keys { if changeKey == key { foundKey = true break KeyFindLoop2 } } }
if !foundKey { return false } }
return true }
// ChangeKey is a key for a change that can be used when subscribing to them.
type ChangeKey struct { Model ChangeModel `bson:"model"` ID string `bson:"id"` }
// ChangeFilter is a filter for listing changes.
type ChangeFilter struct { Keys []ChangeKey EarliestDate *time.Time Author *string Limit *int
PassAll bool // DO NOT EXPOSE
}
|