2022-12-11 02:05:03 +03:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-12-11 16:22:24 +03:00
|
|
|
"log"
|
|
|
|
"net/url"
|
|
|
|
"strings"
|
2022-12-11 02:05:03 +03:00
|
|
|
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
)
|
|
|
|
|
|
|
|
type MongodbStorage struct {
|
|
|
|
Db *mongo.Client
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) CreateUser(user *User) (primitive.ObjectID, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[User](&m, "users")
|
|
|
|
return store.InsertOne(ctx, user)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) GetUserByID(id primitive.ObjectID) (*User, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[User](&m, "users")
|
|
|
|
return store.GetById(ctx, id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) GetUser(filter *bson.D) (*User, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[User](&m, "users")
|
|
|
|
return store.GetOne(ctx, filter)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) GetUsers(filter *bson.D) ([]*User, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[User](&m, "users")
|
|
|
|
return store.GetMany(ctx, filter)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) UpdateUser(user *User) error {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[User](&m, "users")
|
|
|
|
return store.ReplaceByID(ctx, user.Id, user)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) DeleteUser(id primitive.ObjectID) error {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[User](&m, "users")
|
|
|
|
return store.DeleteByID(ctx, id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) CreateSession(s *Session) (primitive.ObjectID, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Session](&m, "sessions")
|
|
|
|
return store.InsertOne(ctx, s)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) GetSessionByToken(token string) (*Session, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Session](&m, "sessions")
|
|
|
|
return store.GetOne(ctx, &bson.D{{Key: "token", Value: token}})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) GetUserSessions(user *User) ([]*Session, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Session](&m, "sessions")
|
|
|
|
return store.GetMany(ctx, &bson.D{{Key: "userid", Value: user.Id}})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) DeleteSession(id primitive.ObjectID) error {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Session](&m, "sessions")
|
|
|
|
return store.DeleteByID(ctx, id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) CreateBookmark(bookmark *Bookmark) (primitive.ObjectID, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Bookmark](&m, "bookmarks")
|
|
|
|
return store.InsertOne(ctx, bookmark)
|
|
|
|
|
|
|
|
}
|
|
|
|
func (m MongodbStorage) GetBookmarkByID(id primitive.ObjectID) (*Bookmark, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Bookmark](&m, "bookmarks")
|
|
|
|
return store.GetById(ctx, id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) GetBookmark(filter *bson.D) (*Bookmark, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Bookmark](&m, "bookmarks")
|
|
|
|
return store.GetOne(ctx, filter)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) GetBookmarks(filter *bson.D) ([]*Bookmark, error) {
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Bookmark](&m, "bookmarks")
|
|
|
|
return store.GetMany(ctx, filter)
|
|
|
|
}
|
|
|
|
|
2022-12-11 16:22:24 +03:00
|
|
|
func (m MongodbStorage) GetRandomBookmarks(count int, filter *bson.D) ([]*Bookmark, error) {
|
|
|
|
passedFilter := getFilter(filter)
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Bookmark](&m, "bookmarks")
|
|
|
|
bookmarks := []*Bookmark{}
|
|
|
|
cur, err := store.Coll.Aggregate(ctx, bson.A{
|
|
|
|
bson.D{{Key: "$match", Value: passedFilter}},
|
|
|
|
bson.D{{Key: "$sample", Value: bson.D{bson.E{Key: "size", Value: count}}}},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Cant aggregate random bookmakrs: ", err)
|
|
|
|
return bookmarks, err
|
|
|
|
}
|
|
|
|
cur.All(ctx, &bookmarks)
|
|
|
|
return bookmarks, err
|
|
|
|
}
|
|
|
|
|
2022-12-11 02:05:03 +03:00
|
|
|
func (m MongodbStorage) GetUserBookmarks(user *User, filter *bson.D) ([]*Bookmark, error) {
|
|
|
|
passedFilter := getFilter(filter)
|
|
|
|
f := bson.D{{Key: "userid", Value: user.Id}}
|
|
|
|
f = append(f, passedFilter...)
|
|
|
|
ctx := context.TODO()
|
|
|
|
store := NewStore[Bookmark](&m, "bookmarks")
|
|
|
|
return store.GetMany(ctx, &f)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m MongodbStorage) Collection(col string) *mongo.Collection {
|
|
|
|
return m.Db.Database("nash").Collection(col)
|
|
|
|
}
|
2022-12-11 16:22:24 +03:00
|
|
|
|
|
|
|
func getFilter(f *bson.D) bson.D {
|
|
|
|
if f == nil {
|
|
|
|
return bson.D{}
|
|
|
|
}
|
|
|
|
return *f
|
|
|
|
}
|
|
|
|
|
|
|
|
func QueryFilter(q *url.Values) bson.D {
|
|
|
|
filter := bson.D{}
|
|
|
|
for k, v := range *q {
|
|
|
|
var f bson.E
|
|
|
|
q := strings.Split(k, "_")
|
|
|
|
if len(q) == 1 { // If param is like "name" or "url" we're using exact matching
|
|
|
|
f = bson.E{Key: k, Value: v[0]}
|
|
|
|
} else {
|
|
|
|
if q[1] == "like" { // If it's like "name_like", we're using regex
|
|
|
|
f = bson.E{Key: q[0], Value: bson.D{{Key: "$regex", Value: v[0]}}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
filter = append(filter, f) // Applying query filters to user filter
|
|
|
|
}
|
|
|
|
return filter
|
|
|
|
}
|