|
|
package mongodb
import ( "context" "errors" "git.aiterp.net/rpdata/api/models" "git.aiterp.net/rpdata/api/repositories" "github.com/globalsign/mgo" "github.com/globalsign/mgo/bson" "strconv" "strings" "time" )
type changeRepository struct { restoreIDs bool changes *mgo.Collection idCounter *counter }
func (r *changeRepository) Find(ctx context.Context, id string) (*models.Change, error) { change := new(models.Change) err := r.changes.FindId(id).One(change) if err != nil { return nil, err }
return change, nil }
func (r *changeRepository) List(ctx context.Context, filter models.ChangeFilter) ([]*models.Change, error) { query := bson.M{} limit := 0 if filter.EarliestDate != nil && !filter.EarliestDate.IsZero() { query["date"] = bson.M{"$gte": *filter.EarliestDate} } if filter.LatestDate != nil && !filter.LatestDate.IsZero() { dateBson, ok := query["date"].(bson.M) if !ok { dateBson = bson.M{} }
dateBson["$gte"] = *filter.EarliestDate } if len(filter.Keys) > 0 { query["keys"] = bson.M{"$in": filter.Keys} } else if !r.restoreIDs { query["listed"] = true } if filter.Author != nil && *filter.Author != "" { query["author"] = *filter.Author } if filter.Limit != nil { limit = *filter.Limit }
initialSize := 64 if limit > 0 && limit < 256 { initialSize = limit }
changes := make([]*models.Change, 0, initialSize) err := r.changes.Find(query).Sort("-date").Limit(limit).All(&changes) if err != nil { return nil, err }
return changes, nil }
func (r *changeRepository) Insert(ctx context.Context, change models.Change) (*models.Change, error) { if !r.restoreIDs || change.ID == "" { next, err := r.idCounter.Increment(1) if err != nil { return nil, err }
change.ID = "Change_" + strconv.Itoa(next) } else { tokens := strings.Split(change.ID, "_") if len(tokens) != 2 || tokens[0] != "Change" { return nil, errors.New("Invalid change ID") }
n, err := strconv.Atoi(tokens[1]) if err != nil { return nil, err }
_ = r.idCounter.Bump(n) }
err := r.changes.Insert(&change) if err != nil { return nil, err }
return &change, nil }
func (r *changeRepository) Remove(ctx context.Context, change models.Change) error { return r.changes.RemoveId(change.ID) }
func newChangeRepository(db *mgo.Database, restoreIDs bool) (repositories.ChangeRepository, error) { collection := db.C("common.changes")
// Delete the old index if it exists.
_ = collection.DropIndexName("date_1")
err := collection.EnsureIndex(mgo.Index{ Name: "expiry", Key: []string{"date"}, ExpireAfter: time.Hour * 2400, // 100 days
}) if err != nil { return nil, err }
err = collection.EnsureIndexKey("author") if err != nil { return nil, err }
err = collection.EnsureIndexKey("keys") if err != nil { return nil, err }
return &changeRepository{ restoreIDs: restoreIDs, changes: collection, idCounter: newCounter(db, "auto_increment", "Change"), }, nil }
|