2021-04-15 22:03:26 +03:00
|
|
|
package mongodb
|
2020-08-24 20:18:05 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2021-04-15 20:26:17 +03:00
|
|
|
"time"
|
|
|
|
|
2021-04-15 21:15:42 +03:00
|
|
|
"github.com/lus/pasty/internal/config"
|
|
|
|
"github.com/lus/pasty/internal/shared"
|
2020-08-24 20:18:05 +03:00
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo/readpref"
|
|
|
|
)
|
|
|
|
|
|
|
|
// MongoDBDriver represents the MongoDB storage driver
|
|
|
|
type MongoDBDriver struct {
|
|
|
|
client *mongo.Client
|
|
|
|
database string
|
|
|
|
collection string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize initializes the MongoDB storage driver
|
|
|
|
func (driver *MongoDBDriver) Initialize() error {
|
|
|
|
// Define the context for the following database operation
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
// Connect to the MongoDB host
|
2021-04-15 21:15:42 +03:00
|
|
|
client, err := mongo.Connect(ctx, options.Client().ApplyURI(config.Current.MongoDB.DSN))
|
2020-08-24 20:18:05 +03:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ping the MongoDB host
|
|
|
|
err = client.Ping(ctx, readpref.Primary())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the driver attributes
|
|
|
|
driver.client = client
|
2021-04-15 21:15:42 +03:00
|
|
|
driver.database = config.Current.MongoDB.Database
|
|
|
|
driver.collection = config.Current.MongoDB.Collection
|
2020-08-24 20:18:05 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Terminate terminates the MongoDB storage driver
|
|
|
|
func (driver *MongoDBDriver) Terminate() error {
|
|
|
|
return driver.client.Disconnect(context.TODO())
|
|
|
|
}
|
|
|
|
|
2020-08-26 22:59:22 +03:00
|
|
|
// ListIDs returns a list of all existing paste IDs
|
|
|
|
func (driver *MongoDBDriver) ListIDs() ([]string, error) {
|
|
|
|
// Define the collection to use for this database operation
|
|
|
|
collection := driver.client.Database(driver.database).Collection(driver.collection)
|
|
|
|
|
|
|
|
// Define the context for the following database operation
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
// Retrieve all paste documents
|
|
|
|
result, err := collection.Find(ctx, bson.M{})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Decode all paste documents
|
2021-04-15 21:15:42 +03:00
|
|
|
var pasteSlice []shared.Paste
|
2020-08-26 22:59:22 +03:00
|
|
|
err = result.All(ctx, &pasteSlice)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read and return the IDs of all paste objects
|
|
|
|
var ids []string
|
|
|
|
for _, paste := range pasteSlice {
|
|
|
|
ids = append(ids, paste.ID)
|
|
|
|
}
|
|
|
|
return ids, nil
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:18:05 +03:00
|
|
|
// Get loads a paste
|
2021-04-15 21:15:42 +03:00
|
|
|
func (driver *MongoDBDriver) Get(id string) (*shared.Paste, error) {
|
2020-08-24 20:18:05 +03:00
|
|
|
// Define the collection to use for this database operation
|
|
|
|
collection := driver.client.Database(driver.database).Collection(driver.collection)
|
|
|
|
|
|
|
|
// Define the context for the following database operation
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
// Try to retrieve the corresponding paste document
|
2020-08-24 21:22:53 +03:00
|
|
|
filter := bson.M{"_id": id}
|
2020-08-24 20:18:05 +03:00
|
|
|
result := collection.FindOne(ctx, filter)
|
|
|
|
err := result.Err()
|
|
|
|
if err != nil {
|
|
|
|
if err == mongo.ErrNoDocuments {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the retrieved paste object
|
2021-04-15 21:15:42 +03:00
|
|
|
paste := new(shared.Paste)
|
2020-08-24 20:18:05 +03:00
|
|
|
err = result.Decode(paste)
|
2020-09-19 02:56:50 +03:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return paste, nil
|
2020-08-24 20:18:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Save saves a paste
|
2021-04-15 21:15:42 +03:00
|
|
|
func (driver *MongoDBDriver) Save(paste *shared.Paste) error {
|
2020-08-24 20:18:05 +03:00
|
|
|
// Define the collection to use for this database operation
|
|
|
|
collection := driver.client.Database(driver.database).Collection(driver.collection)
|
|
|
|
|
|
|
|
// Define the context for the following database operation
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
// Insert the paste object
|
|
|
|
_, err := collection.InsertOne(ctx, paste)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete deletes a paste
|
2020-08-24 21:22:53 +03:00
|
|
|
func (driver *MongoDBDriver) Delete(id string) error {
|
2020-08-24 20:18:05 +03:00
|
|
|
// Define the collection to use for this database operation
|
|
|
|
collection := driver.client.Database(driver.database).Collection(driver.collection)
|
|
|
|
|
|
|
|
// Define the context for the following database operation
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
// Delete the document
|
2020-08-24 21:22:53 +03:00
|
|
|
filter := bson.M{"_id": id}
|
2020-08-24 20:18:05 +03:00
|
|
|
_, err := collection.DeleteOne(ctx, filter)
|
|
|
|
return err
|
|
|
|
}
|
2020-09-19 02:56:50 +03:00
|
|
|
|
|
|
|
// Cleanup cleans up the expired pastes
|
|
|
|
func (driver *MongoDBDriver) Cleanup() (int, error) {
|
|
|
|
// Retrieve all paste IDs
|
|
|
|
ids, err := driver.ListIDs()
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Define the amount of deleted items
|
|
|
|
deleted := 0
|
|
|
|
|
|
|
|
// Loop through all pastes
|
|
|
|
for _, id := range ids {
|
|
|
|
// Retrieve the paste object
|
|
|
|
paste, err := driver.Get(id)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete the paste if it is expired
|
2021-04-15 21:15:42 +03:00
|
|
|
lifetime := config.Current.AutoDelete.Lifetime
|
2020-09-19 02:56:50 +03:00
|
|
|
if paste.AutoDelete && paste.Created+int64(lifetime.Seconds()) < time.Now().Unix() {
|
|
|
|
err = driver.Delete(id)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
deleted++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return deleted, nil
|
|
|
|
}
|