go-mongodb

path: full-stack/go-chi-server/go-mongodb.md

- **fileName**: go-mongodb
- **Created on**: 2024-09-16 15:52:11

installation for mongodb

    go get go.mongodb.org/mongo-driver/mongo

now check for using a go and mongo database code ->:

// connectDB file
package main
import (
    "context"
    "log"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func ConnectDB()(error, *mongo.Client) { // function for connect db
    // connecet db
    ClientOptions := options.Client().
        ApplyURI("mongodb://localhost:27017/go-mongo")
    client, err := mongo.Connect(context.Background(), ClientOptions)
    if err != nil {
        return err, nil
    }
    // now check if connect ot db or not
    if err := client.Ping(context.Background(), nil); err != nil {
        return err, nil
    }else {
        log.Println("Connected to MongoDB")
    }
    return nil, client
}
func closeDB(client *mongo.Client) { // close connection
    // close connection to db
    if err := client.Disconnect(context.Background()); err != nil {
        log.Fatalf("error happend in closeDb", err)
    }
    log.Println("Connection to MongoDB closed")
}
// operation go file
package main

import (
    "context"
    "errors"
    "fmt"
    "time"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
)


type User struct { // the struct user
    ID				string  `bson:"_id,omitempty"`
    Name		        string      `bson:"nomitempty"`
    Email			string  `bson:"email,omitempty"`
    Age				int    `bson:"age,omitempty"`
    IsDelete	        bool    `bson:"is_delete"`
    IsAdmin			bool  `bson:"is_admin"`
    RegisterDate	    string `bson:"register_date,omitempty"`
}

// InsertUserIntoDb insert user into db
func InsertUserIntoDb(client *mongo.Client, user User) (error) {
    // passing to the function the client that return form
    // the connectation to DB Function
    if client == nil { return nil }
    if user.Email == "" { return errors.New("email is required") }
    if user.Name == "" { return errors.New("name is required") }
    // making a collection if not found
    collection := client.Database("go-mongo").Collection("users") 

    // check if the email already exists 
    count, err := collection.CountDocuments(context.Background(), 
        bson.M{"email": user.Email}
        )
    if err != nil { return err }
    if count > 0 { return errors.New("email already exists") }

    _, err = collection.InsertOne(context.Background(), user)
    if err != nil { return err }
    return nil
}

// NewUser create new user struct
func NewUser(name, email string, age int) *User {
    // for get the user date and adding the default data to user
    DataNow := time.Now()
    return &User{
        Name:          name,
        Email:         email,
        Age:           age,
        RegisterDate:  DataNow.Format("2006-01-02 15:04:05"),
        IsDelete:      false,  // Default value
        IsAdmin:       false,  // Default value
    }
}

// GetUser get user from db
func GetUser(client *mongo.Client) (error, []User) {
    if client == nil {
        return errors.New("error happened: something wrong with client"), nil 
    }
    collection := client.Database("go-mongo").Collection("users")
    // Find all users where is_delete = false and is_admin = false
    usersCursor, err := collection.Find(context.Background(), 
        bson.M{"is_delete": false, "is_admin": false},
        )
    if err != nil { return err, nil }
    defer usersCursor.Close(context.Background()) // Close the cursor when done

    // Iterate over the cursor
    var users []User
    for usersCursor.Next(context.Background()) {
        var user User
        if err := usersCursor.Decode(&user); err != nil { return err , nil }
        users = append(users, user)
    }

    // Check for errors that occurred during iteration
    if err := usersCursor.Err(); err != nil { return err ,nil }

    // Print the users
    for _, user := range users { fmt.Printf("\nUser: %+v\n", user) }
    return nil, users
}

// DeleteUser update user in db
func DeleteUser (client *mongo.Client, id string) (error, User) {
    if client == nil { return errors.New("error happened: something wrong with client"), User{} }
    collection := client.Database("go-mongo").Collection("users")

    // find And Delete the user
    user := User{}
    // check first if the user is already deleted
    err := collection.FindOne(context.Background(), bson.M{"_id": id}).Decode(&user)
    if err != nil { return err, User{} }
    if user.IsDelete { return errors.New("user already deleted"), User{} }

    err = collection.FindOneAndUpdate(context.Background(),
        bson.M{"_id": id}, bson.M{"$set": bson.M{"is_delete": true}}).Decode(&user)
    if err != nil { return err, User{} }
    return nil, User{}
}

// SetAdmin update user in db
func SetAdmin (client *mongo.Client, id string) (error, User) {
    if client == nil { return errors.New("error happened: something wrong with client"), User{} }
    collection := client.Database("go-mongo").Collection("users")

    user := User{}
    err := collection.FindOne(context.Background(), bson.M{"_id": id}).Decode(&user)
    if err != nil { return err, User{} }
    if user.IsDelete { return errors.New("user already deleted"), User{} }

    // find And set admin the user
    err = collection.FindOneAndUpdate(context.Background(),
        bson.M{"_id": id}, bson.M{"$set": bson.M{"is_admin": true}}).Decode(&user)

    if err != nil { return err, User{} }
    return nil, User{}
}

// UpdateUser in database mongo 
func UpdateUser (client *mongo.Client, id string, user User) (error, User) {
    if client == nil { return errors.New("error happened: something wrong with client"), User{} }
    collection := client.Database("go-mongo").Collection("users")

    // find And update the user
    err := collection.FindOneAndUpdate(context.Background(),
        bson.M{"_id": id}, bson.M{"$set": user}).Decode(&user)
    if err != nil { return err, User{} }
    return nil, user
}

// main.go file
package main

import (
    "fmt"
    "net/http"
    "log"
)

func main() {
    port := ":8080"
    fmt.Println("listen in port ", port)

    // connect to db
    err, client :=  ConnectDB()
    if err != nil {
        log.Fatalf("error happend in connect to db", err)
    }
    defer closeDB(client) // close the db

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Println("===> welcome from the yossef and server running in port8080")
    })

    // create user
    // user := NewUser("bar", "bar@gmail.com", 25)
    // err = InsertUserIntoDb(client, *user)
    // if err != nil { log.Fatalf("error happend in create user", err) }

    err2, _ := GetUser(client) // return error and all Users
    if err2 != nil { log.Fatalf("error happend in get all users", err) }

    http.ListenAndServe(port, nil)

    return
}

Summary

continue:go-bycript.md
before:go-validator.md]