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
}
-
ConnectDB Function: Establishes a connection to a MongoDB instance running
locally on port 27017 and connects to the database named go-mongo. It also checks
if the connection is successful by pinging the database. If there are errors,
they are returned; otherwise, the connected client is returned. -
closeDB Function: Closes the connection to MongoDB. If there’s an error
while disconnecting, it logs the error and exits the program. -
User Struct: Represents a user document in MongoDB. Fields are tagged for
BSON mapping. -
InsertUserIntoDb: Inserts a new user into the users collection. Checks
if the email already exists before inserting. -
NewUser: Creates a new user with default values for
IsDelete and IsAdmin, and a formatted registration date. -
GetUser: Retrieves users who are not deleted and not admins.
Prints and returns the list of users. -
DeleteUser: Marks a user as deleted without removing the document
from the collection. -
SetAdmin: Promotes a user to admin status.
-
UpdateUser: Updates user details in the database based on the
provided ID. -
main Function: Starts the HTTP server, connects to MongoDB,
and handles requests. It also demonstrates how to use the CRUD
operations but with some lines commented out.
Summary
- Database Connection: connectDB.go handles connection and disconnection
from MongoDB.- CRUD Operations: operation.go provides functions to perform CRUD
operations on the User collection.- Main Application: main.go starts the HTTP server, connects to MongoDB,
and can perform operations like creating users and retrieving them.
continue:go-bycript.md
before:go-validator.md]