diff --git a/database/database.go b/database/database.go index 7c24862..d17c6a0 100644 --- a/database/database.go +++ b/database/database.go @@ -14,6 +14,7 @@ var ErrDriverUnrecognized = errors.New("driver not recognized, check installed v type Database interface { Changes() repositories.ChangeRepository + Channels() repositories.ChannelRepository Characters() repositories.CharacterRepository Tags() repositories.TagRepository Logs() repositories.LogRepository diff --git a/database/mongodb/channels.go b/database/mongodb/channels.go new file mode 100644 index 0000000..54a428d --- /dev/null +++ b/database/mongodb/channels.go @@ -0,0 +1,80 @@ +package mongodb + +import ( + "context" + "git.aiterp.net/rpdata/api/models" + "github.com/globalsign/mgo" + "github.com/globalsign/mgo/bson" +) + +type channelRepository struct { + channels *mgo.Collection +} + +func (r *channelRepository) Find(ctx context.Context, name string) (*models.Channel, error) { + channel := new(models.Channel) + err := r.channels.FindId(name).One(channel) + if err != nil { + return nil, err + } + + return channel, nil +} + +func (r *channelRepository) List(ctx context.Context, filter models.ChannelFilter) ([]*models.Channel, error) { + query := bson.M{} + if filter.Logged != nil { + query["logged"] = *filter.Logged + } + if filter.EventName != nil { + query["eventName"] = *filter.EventName + } + if filter.LocationName != nil { + query["locationName"] = *filter.LocationName + } + + channels := make([]*models.Channel, 0, 32) + err := r.channels.Find(query).Limit(filter.Limit).Sort("_id").All(&channels) + if err != nil { + if err == mgo.ErrNotFound { + return channels, nil + } + + return nil, err + } + + return channels, nil +} + +func (r *channelRepository) Insert(ctx context.Context, channel models.Channel) (*models.Channel, error) { + err := r.channels.Insert(&channel) + if err != nil { + return nil, err + } + + return &channel, nil +} + +func (r *channelRepository) Update(ctx context.Context, channel models.Channel, update models.ChannelUpdate) (*models.Channel, error) { + updateBson := bson.M{} + if update.Logged != nil { + updateBson["logged"] = *update.Logged + } + if update.LocationName != nil { + updateBson["locationName"] = *update.LocationName + } + if update.EventName != nil { + updateBson["eventName"] = *update.EventName + } + + err := r.channels.UpdateId(channel.Name, bson.M{"$set": updateBson}) + if err != nil { + return nil, err + } + + return &channel, nil +} + +func (r *channelRepository) Remove(ctx context.Context, channel models.Channel) error { + return r.channels.RemoveId(channel.Name) +} diff --git a/database/mongodb/db.go b/database/mongodb/db.go index 57ee71c..2db18b6 100644 --- a/database/mongodb/db.go +++ b/database/mongodb/db.go @@ -15,6 +15,7 @@ type MongoDB struct { session *mgo.Session changes repositories.ChangeRepository + channels *channelRepository characters repositories.CharacterRepository tags repositories.TagRepository logs *logRepository @@ -41,6 +42,10 @@ func (m *MongoDB) Posts() repositories.PostRepository { return m.posts } +func (m *MongoDB) Channels() repositories.ChannelRepository { + return m.channels +} + func (m *MongoDB) Close(ctx context.Context) error { m.session.Close() return nil diff --git a/models/channel.go b/models/channel.go index dc8a019..4fd7586 100644 --- a/models/channel.go +++ b/models/channel.go @@ -13,4 +13,20 @@ type Channel struct { // ChangeObject in GQL. func (*Channel) IsChangeObject() { panic("this method is a dummy, and so is its caller") -} \ No newline at end of file +} + +// ChannelFilter is a filter for channel listing. +type ChannelFilter struct { + Logged *bool `json:"logged"` + EventName *string `json:"eventName"` + LocationName *string `json:"locationName"` + Limit int `json:"limit"` +} + +// ChannelUpdate is a filter for channel listing. +type ChannelUpdate struct { + Logged *bool `json:"logged"` + Hub *bool `json:"hub"` + EventName *string `json:"eventName"` + LocationName *string `json:"locationName"` +} diff --git a/repositories/channel.go b/repositories/channel.go new file mode 100644 index 0000000..1c0674b --- /dev/null +++ b/repositories/channel.go @@ -0,0 +1,15 @@ +package repositories + +import ( + "context" + "git.aiterp.net/rpdata/api/models" +) + +// ChannelRepository is an interface for a database using channels. +type ChannelRepository interface { + Find(ctx context.Context, name string) (*models.Channel, error) + List(ctx context.Context, filter models.ChannelFilter) ([]*models.Channel, error) + Insert(ctx context.Context, channel models.Channel) (*models.Channel, error) + Update(ctx context.Context, channel models.Channel, update models.ChannelUpdate) (*models.Channel, error) + Remove(ctx context.Context, channel models.Channel) error +} diff --git a/repositories/character.go b/repositories/character.go index 8ce069f..6ff725a 100644 --- a/repositories/character.go +++ b/repositories/character.go @@ -6,7 +6,7 @@ import ( "git.aiterp.net/rpdata/api/models" ) -// CharacterRepository is an interface for a database using logs. +// CharacterRepository is an interface for a database using characters. type CharacterRepository interface { Find(ctx context.Context, id string) (*models.Character, error) FindNick(ctx context.Context, nick string) (*models.Character, error)