ali2210/WizDwarf

View on GitHub
other/users/adduser.go

Summary

Maintainability
C
1 day
Test Coverage
/* This codebase desgin according to mozilla open source license.
Redistribution , contribution and improve codebase under license
convensions. @contact Ali Hassan AliMatrixCode@protonmail.com */

// Package
package users

// importing packages or libraries
import (
    "context"
    "errors"
    "log"
    "reflect"
    "time"

    "cloud.google.com/go/firestore"
    user "github.com/ali2210/wizdwarf/other/users/register"
    "google.golang.org/api/iterator"
    "google.golang.org/protobuf/types/known/structpb"
)

// constants ...
const (
    collection_name string = "ProfileVisitors"
)

// structs Object which hold information about a single context.
type Doc_Response struct {
    // Profile (without update data )
    Profile user.New_User

    // Updated (after update data)
    Update user.Updated_User
    // Doc_Status {true, false}
    Doc_status bool
}

type (
    // User will access data through various receiver methods.
    DBFirestore interface {
        AddUser(client *firestore.Client, member user.New_User) (*firestore.DocumentRef, *firestore.WriteResult, error)
        GetDocumentById(client *firestore.Client, member user.New_User) (map[string]interface{}, error)
        SearchUser(client *firestore.Client, member user.New_User) (*Doc_Response, error)
        UpdateUserDetails(client *firestore.Client, member user.Updated_User) (*firestore.WriteResult, error)
        GetUpdatedRecord(client *firestore.Client, member user.Updated_User) (map[string]interface{}, error)
    }

    // Firestore_client Empty Object
    FirestoreClient struct{}
)

// This function provide receivers references
func NewCloudInstance() DBFirestore {
    return &FirestoreClient{}
}

// Add user is a simple receiver function which will create a new user account in our database.
// @param : client & user account information
// @return : signature and error
func (*FirestoreClient) AddUser(client *firestore.Client, member user.New_User) (*firestore.DocumentRef, *firestore.WriteResult, error) {

    // create new document
    doc, result, err := client.Collection(collection_name).Add(context.Background(), map[string]interface{}{
        "Name":            member.Name,
        "Email":           member.Email,
        "Password":        member.Password,
        "Lastname":        member.Lastname,
        "Address":         member.Address,
        "Phone":           member.Phone,
        "Zip":             member.Zip,
        "City":            member.City,
        "State":           member.State,
        "Gender":          member.Gender,
        "ID":              member.ID,
        "Friends":         member.Friends,
        "Inspire":         member.Inspire,
        "Lead":            member.Lead,
        "SocialEvolution": member.SocialEvolution,
    })

    // if the document is not created then
    if err != nil {
        return &firestore.DocumentRef{}, result, err
    }
    return doc, result, nil
}

// This function return user credentials when the document is not updated.
// @param client and account
// @return Set and error
func (*FirestoreClient) GetDocumentById(client *firestore.Client, member user.New_User) (map[string]interface{}, error) {

    var result_profile map[string]interface{}

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

    // execute user search query
    query := client.Collection(collection_name).Where("Email", "==", member.Email).Where("ID", "==", member.ID).Documents(ctx)
    for {

        //query return documents then go forward
        doc, err := query.Next()

        // if query return empty document then terminate
        if err == iterator.Done {
            break
        }

        // read document there may be possible while reading something unexpected
        docsnaps, err := doc.Ref.Get(context.Background())
        if err != nil {
            return result_profile, err
        }

        // store document results
        result_profile = docsnaps.Data()

    }
    return result_profile, nil
}

// Search User will return dpcuments if exist... Documents either for new profile and updated profile
// Flag Value                               Description
//  true                                           Document exist
//   false                                        No Document exist

// @param client and user account information
// @return Response and error

func (fire *FirestoreClient) SearchUser(client *firestore.Client, member user.New_User) (*Doc_Response, error) {

    var profile_search map[string]interface{}

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

    // execute user search query
    query := client.Collection(collection_name).Where("Email", "==", member.Email).Where("Password", "==", member.Password).Documents(ctx)

    if reflect.DeepEqual(query, &firestore.DocumentIterator{}) {
        log.Fatalln("Doc iterator empty")
        return &Doc_Response{Profile: user.New_User{}, Update: user.Updated_User{}, Doc_status: false}, errors.New("no user found")
    }

    for {

        //query return documents then go forward
        doc, err := query.Next()
        // if query return empty documednt then terminate
        if err == iterator.Done {
            break
        }

        // read document there may be possible while reading something unexpected
        docsnaps, err := doc.Ref.Get(context.Background())
        if err != nil {
            log.Fatalln("Error getting doc  :", err)
            return &Doc_Response{Profile: user.New_User{}, Update: user.Updated_User{}, Doc_status: false}, err
        }

        if reflect.DeepEqual(docsnaps, map[string]interface{}{}) {
            log.Fatalln("Error empty document")
            return &Doc_Response{Profile: user.New_User{}, Update: user.Updated_User{}, Doc_status: false}, err
        }

        // store document results
        profile_search = docsnaps.Data()
    }

    snaps, err := structpb.NewValue(profile_search)
    if err != nil {
        log.Fatalln("Error data formatting")
        return &Doc_Response{Profile: user.New_User{}, Update: user.Updated_User{}, Doc_status: false}, err
    }

    data, err := snaps.MarshalJSON()
    if err != nil {
        log.Fatalln("Error data marshalling")
        return &Doc_Response{Profile: user.New_User{}, Update: user.Updated_User{}, Doc_status: false}, err
    }

    if err = snaps.UnmarshalJSON(data); err != nil {
        log.Fatalln("Error data new unmarshaling: ")
        return &Doc_Response{Profile: user.New_User{}, Update: user.Updated_User{}, Doc_status: false}, err
    }

    Iterate := reflect.ValueOf(profile_search).MapRange()
    updated := user.Updated_User{}

    for Iterate.Next() {

        if reflect.DeepEqual(Iterate.Key().String(), "Address") {
            updated.Address = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Citation") {
            updated.Citation = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Achievements") {
            updated.Achievements = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Password") {
            updated.Password = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Company") {
            updated.Company = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Lastname") {
            updated.Lastname = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "ID") {
            updated.ID = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "State") {
            updated.State = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Inspire") {
            updated.Inspire = Iterate.Value().Interface().(int64)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "City") {
            updated.City = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Published") {
            updated.Published = Iterate.Value().Interface().(int64)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Date") {
            updated.Date = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Circulum") {
            updated.Circulum = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "University") {
            updated.University = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Zip") {
            updated.Zip = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "SocialEvolution") {
            updated.SocialEvolution = Iterate.Value().Interface().(int64)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Name") {
            updated.Name = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Phone") {
            updated.Phone = Iterate.Value().Interface().(string)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Lead") {
            updated.Lead = Iterate.Value().Interface().(int64)
        }

        if reflect.DeepEqual(Iterate.Key().String(), "Email") {
            updated.Email = Iterate.Value().Interface().(string)
        }

    }

    // If user information is not updated then return old data

    if updated.SocialEvolution == 2 {
        _new := user.New_User{}
        _new.Name = updated.Name
        _new.Email = updated.Email
        _new.Password = updated.Password
        _new.Address = updated.Address
        _new.City = updated.City
        _new.State = updated.State
        _new.ID = updated.ID
        _new.Lastname = updated.Lastname
        _new.Inspire = updated.Inspire
        _new.Friends = updated.Friends
        _new.Lead = updated.Lead
        _new.Zip = updated.Zip
        _new.SocialEvolution = updated.SocialEvolution
        return &Doc_Response{Profile: _new, Update: user.Updated_User{}, Doc_status: true}, nil
    }

    // otherwise .....
    return &Doc_Response{Profile: user.New_User{}, Update: updated, Doc_status: true}, nil

}

// This function will update user information.
// @param client and user information
// @return document signature and error
func (*FirestoreClient) UpdateUserDetails(client *firestore.Client, member user.Updated_User) (*firestore.WriteResult, error) {

    ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
    defer cancel()
    // execute user search query
    query := client.Collection(collection_name).Where("Email", "==", member.Email).Where("ID", "==", member.ID).Documents(ctx)
    var result *firestore.WriteResult
    for {
        // if query return empty documednt then terminate
        doc, err := query.Next()
        if err == iterator.Done {
            break
        }
        // write document there may be possible while reading something unexpected
        result, err = doc.Ref.Set(context.Background(), map[string]interface{}{
            "ID":              member.ID,
            "Name":            member.Name,
            "Email":           member.Email,
            "Phone":           member.Phone,
            "Lastname":        member.Lastname,
            "Address":         member.Address,
            "State":           member.State,
            "City":            member.City,
            "Zip":             member.Zip,
            "Gender":          member.Gender,
            "Status":          member.Status,
            "Suffix":          member.Suffix,
            "University":      member.University,
            "Circulum":        member.Circulum,
            "Company":         member.Company,
            "Date":            member.Date,
            "Published":       member.Published,
            "Achievements":    member.Achievements,
            "Citation":        member.Citation,
            "Friends":         member.Friends,
            "Inspire":         member.Inspire,
            "Lead":            member.Lead,
            "SocialEvolution": member.SocialEvolution,
            "Password":        member.Password,
        })
        if err != nil {
            return &firestore.WriteResult{}, err
        }

        log.Println("Document Updated:", *result)
    }

    return result, nil
}

// This function specified for a simple case. When user will reteive his or her information after adding something.
// @param client and user information
// @return information and error
func (*FirestoreClient) GetUpdatedRecord(client *firestore.Client, member user.Updated_User) (map[string]interface{}, error) {

    var result_profile map[string]interface{}

    ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
    defer cancel()
    // execute user search query
    query := client.Collection(collection_name).Where("Email", "==", member.Email).Where("ID", "==", member.ID).Documents(ctx)
    for {

        //query return documents then go forward
        doc, err := query.Next()

        // if query return empty document then terminate
        if err == iterator.Done {
            break
        }

        // read document there may be possible while reading something unexpected
        docsnaps, err := doc.Ref.Get(ctx)
        if err != nil {
            return result_profile, err
        }

        // store document results
        result_profile = docsnaps.Data()

    }
    return result_profile, nil
}