Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
8.9 kB
1
Indexable
Never
package models

import (
    "context"
    "time"

    "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"
    "your_project/db"
)

type Event struct {
    ID           primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
    Name         string             `bson:"name" binding:"required"`
    Description  string             `bson:"description" binding:"required"`
    Location     string             `bson:"location" binding:"required"`
    FromDateTime time.Time          `bson:"fromDateTime" binding:"required"`
    ToDateTime   time.Time          `bson:"toDateTime" binding:"required"`
    UserID       primitive.ObjectID `bson:"userId"`
}

type EventQuery struct {
    Search     string
    FromDateTime string
    ToDateTime   string
    Filters    map[string]string
    SortField  string
    SortOrder  int
    Limit      int64
}

func (e *Event) Create() (*mongo.InsertOneResult, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    result, err := db.EventCollection.InsertOne(ctx, e)
    return result, err
}

func GetEventByID(id string) (*Event, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    objID, err := primitive.ObjectIDFromHex(id)
    if err != nil {
        return nil, err
    }

    var event Event
    err = db.EventCollection.FindOne(ctx, bson.M{"_id": objID}).Decode(&event)
    return &event, err
}

func (e *Event) Update() (*mongo.UpdateResult, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    update := bson.M{"$set": e}
    result, err := db.EventCollection.UpdateOne(ctx, bson.M{"_id": e.ID}, update)
    return result, err
}

func DeleteEventByID(id string) (*mongo.DeleteResult, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    objID, err := primitive.ObjectIDFromHex(id)
    if err != nil {
        return nil, err
    }

    result, err := db.EventCollection.DeleteOne(ctx, bson.M{"_id": objID})
    return result, err
}

func GetEvents(query EventQuery) ([]Event, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    filter := bson.M{}

    if query.Search != "" {
        filter["$or"] = []bson.M{
            {"name": bson.M{"$regex": query.Search, "$options": "i"}},
            {"description": bson.M{"$regex": query.Search, "$options": "i"}},
            {"location": bson.M{"$regex": query.Search, "$options": "i"}},
        }
    }

    if query.FromDateTime != "" {
        from, _ := time.Parse(time.RFC3339, query.FromDateTime)
        filter["fromDateTime"] = bson.M{"$gte": from}
    }

    if query.ToDateTime != "" {
        to, _ := time.Parse(time.RFC3339, query.ToDateTime)
        if dateTimeFilter, ok := filter["fromDateTime"].(bson.M); ok {
            dateTimeFilter["$lte"] = to
        } else {
            filter["fromDateTime"] = bson.M{"$lte": to}
        }
    }

    for key, value := range query.Filters {
        filter[key] = value
    }

    findOptions := options.Find()
    if query.Limit > 0 {
        findOptions.SetLimit(query.Limit)
    }
    if query.SortField != "" {
        findOptions.SetSort(bson.D{{Key: query.SortField, Value: query.SortOrder}})
    }

    cursor, err := db.EventCollection.Find(ctx, filter, findOptions)
    if err != nil {
        return nil, err
    }
    defer cursor.Close(ctx)

    var events []Event
    for cursor.Next(ctx) {
        var event Event
        if err := cursor.Decode(&event); err != nil {
            return nil, err
        }
        events = append(events, event)
    }
    return events, cursor.Err()
}


__----------------------------------------------------------------------------------------------------------------


package controllers

import (
    "encoding/json"
    "net/http"
    "strconv"

    "github.com/go-chi/chi/v5"
    "github.com/go-chi/chi/v5/middleware"
    "go.mongodb.org/mongo-driver/bson"
    "your_project/models"
)

func CreateEvent(w http.ResponseWriter, r *http.Request) {
    var event models.Event
    if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    result, err := event.Create()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    json.NewEncoder(w).Encode(result)
}

func GetEventByID(w http.ResponseWriter, r *http.Request) {
    id := chi.URLParam(r, "id")
    event, err := models.GetEventByID(id)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    json.NewEncoder(w).Encode(event)
}

func UpdateEvent(w http.ResponseWriter, r *http.Request) {
    id := chi.URLParam(r, "id")
    event, err := models.GetEventByID(id)
    if err != nil {
        http.Error(w, err.Error(), http.StatusNotFound)
        return
    }
    if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    result, err := event.Update()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    json.NewEncoder(w).Encode(result)
}

func DeleteEvent(w http.ResponseWriter, r *http.Request) {
    id := chi.URLParam(r, "id")
    result, err := models.DeleteEventByID(id)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    json.NewEncoder(w).Encode(result)
}

func GetEvents(w http.ResponseWriter, r *http.Request) {
    query := r.URL.Query()
    eventQuery := models.EventQuery{
        Search: query.Get("search"),
        FromDateTime: query.Get("fromDateTime"),
        ToDateTime: query.Get("toDateTime"),
        Filters: map[string]string{},
        SortField: query.Get("sort"),
        SortOrder: 1,
        Limit: 0,
    }

    if query.Get("sortOrder") == "desc" {
        eventQuery.SortOrder = -1
    }

    if limitStr := query.Get("limit"); limitStr != "" {
        limit, _ := strconv.ParseInt(limitStr, 10, 64)
        eventQuery.Limit = limit
    }

    for key, values := range query {
        if key != "search" && key != "fromDateTime" && key != "toDateTime" && key != "sort" && key != "sortOrder" && key != "limit" {
            eventQuery.Filters[key] = values[0]
        }
    }

    events, err := models.GetEvents(eventQuery)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    json.NewEncoder(w).Encode(events)
}

func SetupRouter() *chi.Mux {
    r := chi.NewRouter()
    r.Use(middleware.Logger)

    r.Post("/events", CreateEvent)
    r.Get("/events/{id}", GetEventByID)
    r.Put("/events/{id}", UpdateEvent)
    r.Delete("/events/{id}", DeleteEvent)
    r.Get("/events", GetEvents)

    return r
}


---------------------------------------------------------------------------------------------------------------

package main

import (
    "log"
    "net/http"
    "your_project/controllers"
    "your_project/db"
)

func main() {
    db.Connect()
    defer db.Disconnect()

    r := controllers.SetupRouter()

    log.Println("Starting server on :8080")
    if err := http.ListenAndServe(":8080", r); err != nil {
        log.Fatal(err)
    }
}

---------------------------------------------------------------------------------------------------------


package db

import (
    "context"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

var Client *mongo.Client
var EventCollection *mongo.Collection

func Connect() {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
    client, err := mongo.Connect(ctx, clientOptions)
    if err != nil {
        log.Fatal(err)
    }

    err = client.Ping(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Connected to MongoDB!")
    Client = client
    EventCollection = client.Database("your_database_name").Collection("events")
}

func Disconnect() {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    if err := Client.Disconnect(ctx); err != nil {
        log.Fatal(err)
    }
    log.Println("Disconnected from MongoDB.")
}


Leave a Comment