pilgrim/internal/pilgrim_conf/url_parts.go

144 lines
3.2 KiB
Go

package pilgrim_conf
import (
"fmt"
"log"
"regexp"
"slices"
"strings"
"mvvasilev.dev/pilgrim/internal/pilgrim_common"
)
const EmptyString = ""
type DbDriver string
const (
DbDriver_MySQL DbDriver = "mysql"
DbDriver_MSSQL DbDriver = "mssql"
DbDriver_Postgres DbDriver = "postgres"
DbDriver_Oracle DbDriver = "oracle"
DbDriver_SQLite DbDriver = "sqlite"
DbDriver_MariaDB DbDriver = "mariadb"
)
var AvailableDbDrivers []DbDriver = []DbDriver{
DbDriver_MySQL,
DbDriver_MSSQL,
DbDriver_Postgres,
DbDriver_Oracle,
DbDriver_SQLite,
DbDriver_MariaDB,
}
type UrlParts struct {
Host,
Port,
Username,
Password string
Driver DbDriver
Segments []string
Arguments map[string]string
}
const DbUrlRegex = `^(?:([^:\/?#\s]+):\/{2})?(?:([^@\/?#\s]+)@)?([^\/?#\s]+)?(?:\/([^?#\s]*))?(?:[?]([^#\s]+))?\S*$`
func ParseDatabaseUrl(url string) UrlParts {
urlRegex, err := regexp.Compile(DbUrlRegex)
if err != nil {
log.Fatalf("Regex %s could not be compiled", DbUrlRegex) // The developer wrote the regex wrong.
}
parsed := urlRegex.FindAllStringSubmatch(url, -1)
if parsed == nil || parsed[0] == nil {
return UrlParts{}
}
parsedUrl := parsed[0]
driver := DbDriver(parsedUrl[1])
username := ""
password := ""
host := ""
port := ""
var segments []string
var arguments map[string]string = make(map[string]string)
// Parse username and password ( username:password )
if parsedUrl[2] != EmptyString && strings.Contains(parsedUrl[2], ":") {
splitUserAndPass := strings.Split(parsedUrl[2], ":")
username = splitUserAndPass[0]
password = splitUserAndPass[1]
}
// Parse host and port ( host:port )
if parsedUrl[3] != EmptyString && strings.Contains(parsedUrl[3], ":") {
splitHostAndPort := strings.Split(parsedUrl[3], ":")
host = splitHostAndPort[0]
port = splitHostAndPort[1]
}
// Parse segments ( segment1/segment2 )
if parsedUrl[4] != EmptyString {
segments = ParseSegments(parsedUrl[4])
}
// Parse arguments ( arg1=value1&arg2=value2 )
if parsedUrl[5] != EmptyString {
arguments = ParseArguments(parsedUrl[5])
}
return UrlParts{
Driver: driver,
Username: username,
Password: password,
Host: host,
Port: port,
Segments: segments,
Arguments: arguments,
}
}
func ParseSegments(segments string) []string {
if segments == EmptyString {
return []string{}
}
return strings.Split(segments, "/")
}
func ParseArguments(arguments string) map[string]string {
if arguments == EmptyString {
return make(map[string]string)
}
var argsMap map[string]string = make(map[string]string)
splitArguments := strings.Split(arguments, "&")
for _, arg := range splitArguments {
if !strings.Contains(arg, "=") {
continue
}
splitArgAndValue := strings.Split(arg, "=")
argsMap[splitArgAndValue[0]] = splitArgAndValue[1]
}
return argsMap
}
// Returns true if valid, with nil error, or false if invalid, with the validation error
func (urlParts *UrlParts) Validate() (bool, error) {
if !slices.Contains(AvailableDbDrivers, DbDriver(urlParts.Driver)) {
return false, pilgrim_common.PilgrimInvalidError(fmt.Sprintf("URLParts invalid: Provided driver \"%v\" is not currently supported ( must be one of %v )", urlParts.Driver, AvailableDbDrivers))
}
return true, nil
}