mydb/adapter/mongo/connection.go

99 lines
1.7 KiB
Go
Raw Normal View History

2023-09-18 15:15:42 +08:00
package mongo
import (
"fmt"
"net/url"
"strings"
)
const connectionScheme = `mongodb`
// ConnectionURL implements a MongoDB connection struct.
type ConnectionURL struct {
User string
Password string
Host string
Database string
Options map[string]string
}
func (c ConnectionURL) String() (s string) {
if c.Database == "" {
return ""
}
vv := url.Values{}
// Do we have any options?
if c.Options == nil {
c.Options = map[string]string{}
}
// Converting options into URL values.
for k, v := range c.Options {
vv.Set(k, v)
}
// Has user?
var userInfo *url.Userinfo
if c.User != "" {
if c.Password == "" {
userInfo = url.User(c.User)
} else {
userInfo = url.UserPassword(c.User, c.Password)
}
}
// Building URL.
u := url.URL{
Scheme: connectionScheme,
Path: c.Database,
Host: c.Host,
User: userInfo,
RawQuery: vv.Encode(),
}
return u.String()
}
// ParseURL parses s into a ConnectionURL struct.
func ParseURL(s string) (conn ConnectionURL, err error) {
var u *url.URL
if !strings.HasPrefix(s, connectionScheme+"://") {
return conn, fmt.Errorf(`Expecting mongodb:// connection scheme.`)
}
if u, err = url.Parse(s); err != nil {
return conn, err
}
conn.Host = u.Host
// Deleting / from start of the string.
conn.Database = strings.Trim(u.Path, "/")
// Adding user / password.
if u.User != nil {
conn.User = u.User.Username()
conn.Password, _ = u.User.Password()
}
// Adding options.
conn.Options = map[string]string{}
var vv url.Values
if vv, err = url.ParseQuery(u.RawQuery); err != nil {
return conn, err
}
for k := range vv {
conn.Options[k] = vv.Get(k)
}
return conn, err
}