github.com/abolfazlbeh/zhycan@v0.0.0-20230819144214-24cf38237387/internal/db/mongo_wrapper.go (about)

     1  package db
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"github.com/abolfazlbeh/zhycan/internal/config"
     8  	"go.mongodb.org/mongo-driver/mongo"
     9  	"go.mongodb.org/mongo-driver/mongo/options"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  // Mark: Definitions
    15  
    16  // SqlWrapper struct
    17  type MongoWrapper struct {
    18  	name             string
    19  	config           *Mongo
    20  	databaseInstance *mongo.Client
    21  }
    22  
    23  func (m *MongoWrapper) init(name string) error {
    24  	m.name = name
    25  
    26  	// reading config
    27  	nameParts := strings.Split(m.name, "/")
    28  
    29  	var tempConfig *Mongo
    30  	tempConfigObj, err := config.GetManager().Get(nameParts[0], nameParts[1])
    31  	if err == nil {
    32  		// first marshal
    33  		configData, err := json.Marshal(tempConfigObj)
    34  		if err == nil {
    35  			_ = json.Unmarshal(configData, &tempConfig)
    36  		}
    37  	}
    38  	m.config = tempConfig
    39  
    40  	//dbNameKey := fmt.Sprintf("%s.%s", nameParts[1], "db")
    41  	//dbNameStr, err := config.GetManager().Get(nameParts[0], dbNameKey)
    42  	//if err != nil {
    43  	//	return err
    44  	//}
    45  	//
    46  	//hostKey := fmt.Sprintf("%s.%s", nameParts[1], "host")
    47  	//hostStr, err := config.GetManager().Get(nameParts[0], hostKey)
    48  	//if err != nil {
    49  	//	return err
    50  	//}
    51  	//
    52  	//portKey := fmt.Sprintf("%s.%s", nameParts[1], "port")
    53  	//portStr, err := config.GetManager().Get(nameParts[0], portKey)
    54  	//if err != nil {
    55  	//	return err
    56  	//}
    57  	//
    58  	//usernameKey := fmt.Sprintf("%s.%s", nameParts[1], "username")
    59  	//usernameStr, err := config.GetManager().Get(nameParts[0], usernameKey)
    60  	//if err != nil {
    61  	//	return err
    62  	//}
    63  	//
    64  	//passwordKey := fmt.Sprintf("%s.%s", nameParts[1], "password")
    65  	//passwordStr, err := config.GetManager().Get(nameParts[0], passwordKey)
    66  	//if err != nil {
    67  	//	return err
    68  	//}
    69  
    70  	optionsKey := fmt.Sprintf("%s.%s", nameParts[1], "options")
    71  	optionsObj, err := config.GetManager().Get(nameParts[0], optionsKey)
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	optionsMap := make(map[string]string, len(optionsObj.(map[string]interface{})))
    77  	for key, item := range optionsObj.(map[string]interface{}) {
    78  		optionsMap[key] = item.(string)
    79  	}
    80  	m.config.Options = optionsMap
    81  
    82  	var internalLogger *MongoLoggerConfig
    83  
    84  	internalLoggerKey := fmt.Sprintf("%s.%s", nameParts[1], "logger")
    85  	internalLoggerObj, err := config.GetManager().Get(nameParts[0], internalLoggerKey)
    86  	if err == nil {
    87  		// first marshal
    88  		configData, err := json.Marshal(internalLoggerObj)
    89  		if err == nil {
    90  			_ = json.Unmarshal(configData, &internalLogger)
    91  		}
    92  	}
    93  	m.config.LoggerConfig = internalLogger
    94  
    95  	//m.config = &Mongo{
    96  	//	DatabaseName: dbNameStr.(string),
    97  	//	Username:     usernameStr.(string),
    98  	//	Password:     passwordStr.(string),
    99  	//	Host:         hostStr.(string),
   100  	//	Port:         portStr.(string),
   101  	//	Options:      optionsMap,
   102  	//}
   103  	return nil
   104  }
   105  
   106  func (m *MongoWrapper) makeUri() string {
   107  	optionsQSArr := make([]string, 0)
   108  	for key, val := range m.config.Options {
   109  		optionsQSArr = append(optionsQSArr, fmt.Sprintf("%s=%s", key, val))
   110  	}
   111  	optionsQS := strings.Join(optionsQSArr, "&")
   112  
   113  	return fmt.Sprintf("mongodb://%s:%s@%s:%s/?%s",
   114  		m.config.Username,
   115  		m.config.Password,
   116  		m.config.Host,
   117  		m.config.Port,
   118  		optionsQS)
   119  }
   120  
   121  // MARK: Public functions
   122  
   123  // GetDb - return associated internal Db
   124  func (m *MongoWrapper) GetDb() (*mongo.Client, error) {
   125  	if m.databaseInstance == nil {
   126  		uri := m.makeUri()
   127  
   128  		// Configure Logger Options
   129  		loggerOptions := options.Logger().SetSink(&MongoLogger{}).SetMaxDocumentLength(uint(m.config.LoggerConfig.MaxDocumentLength))
   130  		switch m.config.LoggerConfig.ComponentConnection {
   131  		case "info":
   132  			loggerOptions = loggerOptions.SetComponentLevel(options.LogComponentConnection, options.LogLevelInfo)
   133  		default:
   134  			loggerOptions = loggerOptions.SetComponentLevel(options.LogComponentConnection, options.LogLevelDebug)
   135  		}
   136  
   137  		switch m.config.LoggerConfig.ComponentCommand {
   138  		case "info":
   139  			loggerOptions = loggerOptions.SetComponentLevel(options.LogComponentCommand, options.LogLevelInfo)
   140  		default:
   141  			loggerOptions = loggerOptions.SetComponentLevel(options.LogComponentCommand, options.LogLevelDebug)
   142  		}
   143  
   144  		db, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri).SetLoggerOptions(loggerOptions))
   145  		if err != nil {
   146  			return nil, err
   147  		}
   148  
   149  		ctx, _ := context.WithTimeout(context.TODO(), 1*time.Second)
   150  		errPing := db.Ping(ctx, nil)
   151  		if errPing != nil {
   152  			return nil, errPing
   153  		}
   154  
   155  		m.databaseInstance = db
   156  	}
   157  
   158  	return m.databaseInstance, nil
   159  }
   160  
   161  // NewMongoWrapper - create a new instance of MongoWrapper and returns it
   162  func NewMongoWrapper(name string) (*MongoWrapper, error) {
   163  	wrapper := &MongoWrapper{}
   164  	err := wrapper.init(name)
   165  	if err != nil {
   166  		return nil, NewCreateMongoWrapperErr(err)
   167  	}
   168  
   169  	return wrapper, nil
   170  }