201 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package storage
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"log"
 | 
						|
	"net/url"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"go.mongodb.org/mongo-driver/bson"
 | 
						|
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
						|
	"go.mongodb.org/mongo-driver/mongo"
 | 
						|
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
						|
)
 | 
						|
 | 
						|
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)
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
}
 | 
						|
 | 
						|
func (m MongodbStorage) GetLastBookmarks(count int, filter *bson.D) ([]*Bookmark, error) {
 | 
						|
	passedFilter := getFilter(filter)
 | 
						|
	ctx := context.TODO()
 | 
						|
	store := NewStore[Bookmark](&m, "bookmarks")
 | 
						|
	bookmarks := []*Bookmark{}
 | 
						|
	opts := options.Find().SetSort(bson.D{{Key: "created", Value: -1}}).SetLimit(int64(count))
 | 
						|
	cur, err := store.Coll.Find(ctx, passedFilter, opts)
 | 
						|
	if err != nil {
 | 
						|
		log.Println("Cant find last bookmakrs: ", err)
 | 
						|
		return bookmarks, err
 | 
						|
	}
 | 
						|
	cur.All(ctx, &bookmarks)
 | 
						|
	return bookmarks, err
 | 
						|
}
 | 
						|
 | 
						|
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) CreateFolder(folder *Folder) (primitive.ObjectID, error) {
 | 
						|
	store := NewStore[Folder](&m, "folders")
 | 
						|
	return store.InsertOne(context.TODO(), folder)
 | 
						|
}
 | 
						|
 | 
						|
func (m MongodbStorage) GetFolderByID(id primitive.ObjectID) (*Folder, error) {
 | 
						|
	store := NewStore[Folder](&m, "folders")
 | 
						|
	return store.GetById(context.TODO(), id)
 | 
						|
}
 | 
						|
 | 
						|
func (m MongodbStorage) GetFolder(filter *bson.D) (*Folder, error) {
 | 
						|
	store := NewStore[Folder](&m, "folders")
 | 
						|
	return store.GetOne(context.TODO(), filter)
 | 
						|
}
 | 
						|
 | 
						|
func (m MongodbStorage) GetFolders(filter *bson.D) ([]*Folder, error) {
 | 
						|
	store := NewStore[Folder](&m, "folders")
 | 
						|
	return store.GetMany(context.TODO(), filter)
 | 
						|
}
 | 
						|
 | 
						|
func (m MongodbStorage) GetChildrenFolders(id primitive.ObjectID) ([]*Folder, error) {
 | 
						|
	store := NewStore[Folder](&m, "folders")
 | 
						|
	return store.GetMany(context.TODO(), &bson.D{{Key: "parentid", Value: id}})
 | 
						|
}
 | 
						|
 | 
						|
func (m MongodbStorage) GetChildrenBookmarks(id primitive.ObjectID) ([]*Bookmark, error) {
 | 
						|
	store := NewStore[Bookmark](&m, "bookmarks")
 | 
						|
	return store.GetMany(context.TODO(), &bson.D{{Key: "folderid", Value: id}})
 | 
						|
}
 | 
						|
 | 
						|
func (m MongodbStorage) Collection(col string) *mongo.Collection {
 | 
						|
	return m.Db.Database("nash").Collection(col)
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
}
 |