1
0
mirror of https://github.com/lus/pasty.git synced 2023-08-10 21:13:09 +03:00
pasty/internal/storage/mongodb/mongodb_driver.go

171 lines
4.4 KiB
Go
Raw Normal View History

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())
}
// 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
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
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
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
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
}