package channel import ( "errors" "strings" "git.aiterp.net/rpdata/api/internal/store" "github.com/globalsign/mgo" "github.com/globalsign/mgo/bson" ) var collection *mgo.Collection // ErrInvalidName is an error for an invalid channel name var ErrInvalidName = errors.New("Invalid channel name") // A Channel represents information abount an IRC RP channel, and whether it should be logged type Channel struct { Name string `bson:"_id"` Logged bool `bson:"logged"` Hub bool `bson:"hub"` EventName string `bson:"event,omitempty"` LocationName string `bson:"location,omitempty"` } // Filter for searching type Filter struct { Logged *bool `json:"logged"` EventName string `json:"eventName"` LocationName string `json:"locationName"` } // Edit edits the channel func (channel *Channel) Edit(logged, hub *bool, event, location *string) error { changes := bson.M{} changed := *channel if logged != nil && channel.Logged != *logged { changes["logged"] = *logged changed.Logged = *logged } if hub != nil && channel.Hub != *hub { changes["hub"] = *hub changed.Hub = *hub } if event != nil && channel.EventName != *event { changes["event"] = *event changed.EventName = *event } if location != nil && channel.LocationName != *location { changes["location"] = *location changed.LocationName = *location } if len(changes) == 0 { return nil } err := collection.UpdateId(channel.Name, bson.M{"$set": changes}) if err != nil { return err } *channel = changed return nil } // Remove removes the channel information from the database. func (channel *Channel) Remove() error { return collection.RemoveId(channel.Name) } // Ensure ensures a channel's existence. It does not change `logged` if there is // an existing channel. func Ensure(name string, logged bool) (Channel, error) { channel, err := FindName(name) if err == mgo.ErrNotFound { return New(name, logged, false, "", "") } else if err != nil { return Channel{}, err } return channel, nil } // New creates a new channel func New(name string, logged, hub bool, event, location string) (Channel, error) { if len(name) < 3 && !strings.HasPrefix(name, "#") { return Channel{}, ErrInvalidName } channel := Channel{ Name: name, Logged: logged, Hub: hub, EventName: event, LocationName: location, } err := collection.Insert(channel) if err != nil { return Channel{}, err } return channel, nil } // FindName finds a channel by its id (its name). func FindName(name string) (Channel, error) { channel := Channel{} err := collection.FindId(name).One(&channel) return channel, err } // List finds channels, if logged is true it will be limited to logged // channels func List(filter *Filter) ([]Channel, error) { query := bson.M{} if filter != nil { if filter.Logged != nil { query["logged"] = *filter.Logged } if filter.EventName != "" { query["eventName"] = filter.EventName } if filter.LocationName != "" { query["locationName"] = filter.LocationName } } channels := make([]Channel, 0, 128) err := collection.Find(query).All(&channels) return channels, err } // ListNames finds channels by the names provided func ListNames(names ...string) ([]Channel, error) { query := bson.M{"_id": bson.M{"$in": names}} channels := make([]Channel, 0, 32) err := collection.Find(query).All(&channels) return channels, err } func init() { store.HandleInit(func(db *mgo.Database) { collection = db.C("common.channels") collection.EnsureIndexKey("logged") collection.EnsureIndexKey("hub") collection.EnsureIndexKey("event") collection.EnsureIndexKey("location") }) }