mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 05:09:58 +00:00
STOR-519: Add db-connect, a SQL over HTTPS server
This commit is contained in:
596
vendor/github.com/xo/dburl/dsn.go
generated
vendored
Normal file
596
vendor/github.com/xo/dburl/dsn.go
generated
vendored
Normal file
@@ -0,0 +1,596 @@
|
||||
package dburl
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
stdpath "path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GenScheme returns a func that generates a scheme:// style DSN from the
|
||||
// passed URL.
|
||||
func GenScheme(scheme string) func(*URL) (string, error) {
|
||||
return func(u *URL) (string, error) {
|
||||
z := &url.URL{
|
||||
Scheme: scheme,
|
||||
Opaque: u.Opaque,
|
||||
User: u.User,
|
||||
Host: u.Host,
|
||||
Path: u.Path,
|
||||
RawPath: u.RawPath,
|
||||
RawQuery: u.RawQuery,
|
||||
Fragment: u.Fragment,
|
||||
}
|
||||
|
||||
return z.String(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// GenFromURL returns a func that generates a DSN using urlstr as the default
|
||||
// URL parameters, overriding the values only if when in the passed URL.
|
||||
func GenFromURL(urlstr string) func(*URL) (string, error) {
|
||||
z, err := url.Parse(urlstr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return func(u *URL) (string, error) {
|
||||
opaque := z.Opaque
|
||||
if u.Opaque != "" {
|
||||
opaque = u.Opaque
|
||||
}
|
||||
|
||||
user := z.User
|
||||
if u.User != nil {
|
||||
user = u.User
|
||||
}
|
||||
|
||||
host, port := hostname(z.Host), hostport(z.Host)
|
||||
if h := hostname(u.Host); h != "" {
|
||||
host = h
|
||||
}
|
||||
if p := hostport(u.Host); p != "" {
|
||||
port = p
|
||||
}
|
||||
if port != "" {
|
||||
host += ":" + port
|
||||
}
|
||||
|
||||
path := z.Path
|
||||
if u.Path != "" {
|
||||
path = u.Path
|
||||
}
|
||||
|
||||
rawPath := z.RawPath
|
||||
if u.RawPath != "" {
|
||||
rawPath = u.RawPath
|
||||
}
|
||||
|
||||
q := z.Query()
|
||||
for k, v := range u.Query() {
|
||||
q.Set(k, strings.Join(v, " "))
|
||||
}
|
||||
|
||||
fragment := z.Fragment
|
||||
if u.Fragment != "" {
|
||||
fragment = u.Fragment
|
||||
}
|
||||
|
||||
y := &url.URL{
|
||||
Scheme: z.Scheme,
|
||||
Opaque: opaque,
|
||||
User: user,
|
||||
Host: host,
|
||||
Path: path,
|
||||
RawPath: rawPath,
|
||||
RawQuery: q.Encode(),
|
||||
Fragment: fragment,
|
||||
}
|
||||
|
||||
return y.String(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// GenOpaque generates a opaque file path DSN from the passed URL.
|
||||
func GenOpaque(u *URL) (string, error) {
|
||||
if u.Opaque == "" {
|
||||
return "", ErrMissingPath
|
||||
}
|
||||
|
||||
return u.Opaque + genQueryOptions(u.Query()), nil
|
||||
}
|
||||
|
||||
// GenPostgres generates a postgres DSN from the passed URL.
|
||||
func GenPostgres(u *URL) (string, error) {
|
||||
host, port, dbname := hostname(u.Host), hostport(u.Host), strings.TrimPrefix(u.Path, "/")
|
||||
if host == "." {
|
||||
return "", ErrRelativePathNotSupported
|
||||
}
|
||||
|
||||
// resolve path
|
||||
if u.Proto == "unix" {
|
||||
if host == "" {
|
||||
dbname = "/" + dbname
|
||||
}
|
||||
|
||||
host, port, dbname = resolveDir(stdpath.Join(host, dbname))
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
q.Set("host", host)
|
||||
q.Set("port", port)
|
||||
q.Set("dbname", dbname)
|
||||
|
||||
// add user/pass
|
||||
if u.User != nil {
|
||||
q.Set("user", u.User.Username())
|
||||
pass, _ := u.User.Password()
|
||||
q.Set("password", pass)
|
||||
}
|
||||
|
||||
// save host, port, dbname
|
||||
if u.hostPortDB == nil {
|
||||
u.hostPortDB = []string{host, port, dbname}
|
||||
}
|
||||
|
||||
return genOptions(q, "", "=", " ", ",", true), nil
|
||||
}
|
||||
|
||||
// GenSQLServer generates a mssql DSN from the passed URL.
|
||||
func GenSQLServer(u *URL) (string, error) {
|
||||
host, port, dbname := hostname(u.Host), hostport(u.Host), strings.TrimPrefix(u.Path, "/")
|
||||
|
||||
// add instance name to host if present
|
||||
if i := strings.Index(dbname, "/"); i != -1 {
|
||||
host = host + `\` + dbname[:i]
|
||||
dbname = dbname[i+1:]
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
q.Set("Server", host)
|
||||
q.Set("Port", port)
|
||||
q.Set("Database", dbname)
|
||||
|
||||
// add user/pass
|
||||
if u.User != nil {
|
||||
q.Set("User ID", u.User.Username())
|
||||
pass, _ := u.User.Password()
|
||||
q.Set("Password", pass)
|
||||
}
|
||||
|
||||
// save host, port, dbname
|
||||
if u.hostPortDB == nil {
|
||||
u.hostPortDB = []string{host, port, dbname}
|
||||
}
|
||||
|
||||
return genOptionsODBC(q, true), nil
|
||||
}
|
||||
|
||||
// // GenSybase generates a sqlany DSN from the passed URL.
|
||||
// func GenSybase(u *URL) (string, error) {
|
||||
// // of format "UID=DBA;PWD=sql;Host=demo12;DatabaseName=demo;ServerName=myserver"
|
||||
// host, port, dbname := hostname(u.Host), hostport(u.Host), strings.TrimPrefix(u.Path, "/")
|
||||
//
|
||||
// // add instance name to host if present
|
||||
// if i := strings.Index(dbname, "/"); i != -1 {
|
||||
// host = host + `\` + dbname[:i]
|
||||
// dbname = dbname[i+1:]
|
||||
// }
|
||||
//
|
||||
// q := u.Query()
|
||||
// q.Set("Host", host)
|
||||
// if port != "" {
|
||||
// q.Set("LINKS", "tcpip(PORT="+port+")")
|
||||
// }
|
||||
// q.Set("DatabaseName", dbname)
|
||||
//
|
||||
// // add user/pass
|
||||
// if u.User != nil {
|
||||
// q.Set("UID", u.User.Username())
|
||||
// pass, _ := u.User.Password()
|
||||
// q.Set("PWD", pass)
|
||||
// }
|
||||
//
|
||||
// // save host, port, dbname
|
||||
// if u.hostPortDB == nil {
|
||||
// u.hostPortDB = []string{host, port, dbname}
|
||||
// }
|
||||
//
|
||||
// return genOptionsODBC(q, true), nil
|
||||
// }
|
||||
|
||||
// GenMySQL generates a mysql DSN from the passed URL.
|
||||
func GenMySQL(u *URL) (string, error) {
|
||||
host, port, dbname := hostname(u.Host), hostport(u.Host), strings.TrimPrefix(u.Path, "/")
|
||||
|
||||
var dsn string
|
||||
|
||||
// build user/pass
|
||||
if u.User != nil {
|
||||
if un := u.User.Username(); len(un) > 0 {
|
||||
if up, ok := u.User.Password(); ok {
|
||||
un += ":" + up
|
||||
}
|
||||
dsn += un + "@"
|
||||
}
|
||||
}
|
||||
|
||||
// resolve path
|
||||
if u.Proto == "unix" {
|
||||
if host == "" {
|
||||
dbname = "/" + dbname
|
||||
}
|
||||
host, dbname = resolveSocket(stdpath.Join(host, dbname))
|
||||
port = ""
|
||||
}
|
||||
|
||||
// save host, port, dbname
|
||||
if u.hostPortDB == nil {
|
||||
u.hostPortDB = []string{host, port, dbname}
|
||||
}
|
||||
|
||||
// if host or proto is not empty
|
||||
if u.Proto != "unix" {
|
||||
if host == "" {
|
||||
host = "127.0.0.1"
|
||||
}
|
||||
if port == "" {
|
||||
port = "3306"
|
||||
}
|
||||
}
|
||||
if port != "" {
|
||||
port = ":" + port
|
||||
}
|
||||
|
||||
dsn += u.Proto + "(" + host + port + ")"
|
||||
|
||||
// add database name
|
||||
dsn += "/" + dbname
|
||||
|
||||
return dsn + genQueryOptions(u.Query()), nil
|
||||
}
|
||||
|
||||
// GenMyMySQL generates a MyMySQL MySQL DSN from the passed URL.
|
||||
func GenMyMySQL(u *URL) (string, error) {
|
||||
host, port, dbname := hostname(u.Host), hostport(u.Host), strings.TrimPrefix(u.Path, "/")
|
||||
|
||||
// resolve path
|
||||
if u.Proto == "unix" {
|
||||
if host == "" {
|
||||
dbname = "/" + dbname
|
||||
}
|
||||
host, dbname = resolveSocket(stdpath.Join(host, dbname))
|
||||
port = ""
|
||||
}
|
||||
|
||||
// save host, port, dbname
|
||||
if u.hostPortDB == nil {
|
||||
u.hostPortDB = []string{host, port, dbname}
|
||||
}
|
||||
|
||||
// if host or proto is not empty
|
||||
if u.Proto != "unix" {
|
||||
if host == "" {
|
||||
host = "127.0.0.1"
|
||||
}
|
||||
if port == "" {
|
||||
port = "3306"
|
||||
}
|
||||
}
|
||||
if port != "" {
|
||||
port = ":" + port
|
||||
}
|
||||
|
||||
dsn := u.Proto + ":" + host + port
|
||||
|
||||
// add opts
|
||||
dsn += genOptions(
|
||||
convertOptions(u.Query(), "true", ""),
|
||||
",", "=", ",", " ", false,
|
||||
)
|
||||
|
||||
// add dbname
|
||||
dsn += "*" + dbname
|
||||
|
||||
// add user/pass
|
||||
if u.User != nil {
|
||||
pass, _ := u.User.Password()
|
||||
dsn += "/" + u.User.Username() + "/" + pass
|
||||
} else if strings.HasSuffix(dsn, "*") {
|
||||
dsn += "//"
|
||||
}
|
||||
|
||||
return dsn, nil
|
||||
}
|
||||
|
||||
// GenOracle generates a ora DSN from the passed URL.
|
||||
func GenOracle(u *URL) (string, error) {
|
||||
// create dsn
|
||||
dsn := u.Host + u.Path
|
||||
|
||||
// build user/pass
|
||||
var un string
|
||||
if u.User != nil {
|
||||
if un = u.User.Username(); len(un) > 0 {
|
||||
if up, ok := u.User.Password(); ok {
|
||||
un += "/" + up
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return un + "@" + dsn, nil
|
||||
}
|
||||
|
||||
// GenFirebird generates a firebirdsql DSN from the passed URL.
|
||||
func GenFirebird(u *URL) (string, error) {
|
||||
z := &url.URL{
|
||||
User: u.User,
|
||||
Host: u.Host,
|
||||
Path: u.Path,
|
||||
RawPath: u.RawPath,
|
||||
RawQuery: u.RawQuery,
|
||||
Fragment: u.Fragment,
|
||||
}
|
||||
return strings.TrimPrefix(z.String(), "//"), nil
|
||||
}
|
||||
|
||||
// GenADODB generates a adodb DSN from the passed URL.
|
||||
func GenADODB(u *URL) (string, error) {
|
||||
// grab data source
|
||||
host, port := hostname(u.Host), hostport(u.Host)
|
||||
dsname, dbname := strings.TrimPrefix(u.Path, "/"), ""
|
||||
if dsname == "" {
|
||||
dsname = "."
|
||||
}
|
||||
|
||||
// check if data source is not a path on disk
|
||||
if mode(dsname) == 0 {
|
||||
if i := strings.IndexAny(dsname, `\/`); i != -1 {
|
||||
dbname = dsname[i+1:]
|
||||
dsname = dsname[:i]
|
||||
}
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
q.Set("Provider", host)
|
||||
q.Set("Port", port)
|
||||
q.Set("Data Source", dsname)
|
||||
q.Set("Database", dbname)
|
||||
|
||||
// add user/pass
|
||||
if u.User != nil {
|
||||
q.Set("User ID", u.User.Username())
|
||||
pass, _ := u.User.Password()
|
||||
q.Set("Password", pass)
|
||||
}
|
||||
|
||||
// save host, port, dbname
|
||||
if u.hostPortDB == nil {
|
||||
n := dsname
|
||||
if dbname != "" {
|
||||
n += "/" + dbname
|
||||
}
|
||||
u.hostPortDB = []string{host, port, n}
|
||||
}
|
||||
|
||||
return genOptionsODBC(q, true), nil
|
||||
}
|
||||
|
||||
// GenODBC generates a odbc DSN from the passed URL.
|
||||
func GenODBC(u *URL) (string, error) {
|
||||
q := u.Query()
|
||||
|
||||
host, port, dbname := hostname(u.Host), hostport(u.Host), strings.TrimPrefix(u.Path, "/")
|
||||
|
||||
// save host, port, dbname
|
||||
if u.hostPortDB == nil {
|
||||
u.hostPortDB = []string{host, port, dbname}
|
||||
}
|
||||
|
||||
q.Set("Driver", "{"+strings.Replace(u.Proto, "+", " ", -1)+"}")
|
||||
q.Set("Server", host)
|
||||
|
||||
if port == "" {
|
||||
proto := strings.ToLower(u.Proto)
|
||||
switch {
|
||||
case strings.Contains(proto, "mysql"):
|
||||
q.Set("Port", "3306")
|
||||
case strings.Contains(proto, "postgres"):
|
||||
q.Set("Port", "5432")
|
||||
case strings.Contains(proto, "db2") || strings.Contains(proto, "ibm"):
|
||||
q.Set("ServiceName", "50000")
|
||||
default:
|
||||
q.Set("Port", "1433")
|
||||
}
|
||||
} else {
|
||||
q.Set("Port", port)
|
||||
}
|
||||
q.Set("Database", dbname)
|
||||
|
||||
// add user/pass
|
||||
if u.User != nil {
|
||||
q.Set("UID", u.User.Username())
|
||||
p, _ := u.User.Password()
|
||||
q.Set("PWD", p)
|
||||
}
|
||||
|
||||
return genOptionsODBC(q, true), nil
|
||||
}
|
||||
|
||||
// GenOLEODBC generates a oleodbc DSN from the passed URL.
|
||||
func GenOLEODBC(u *URL) (string, error) {
|
||||
props, err := GenODBC(u)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return `Provider=MSDASQL.1;Extended Properties="` + props + `"`, nil
|
||||
}
|
||||
|
||||
// GenClickhouse generates a clickhouse DSN from the passed URL.
|
||||
func GenClickhouse(u *URL) (string, error) {
|
||||
z := &url.URL{
|
||||
Scheme: "tcp",
|
||||
Opaque: u.Opaque,
|
||||
Host: u.Host,
|
||||
Path: u.Path,
|
||||
RawPath: u.RawPath,
|
||||
RawQuery: u.RawQuery,
|
||||
Fragment: u.Fragment,
|
||||
}
|
||||
|
||||
if hostport(z.Host) == "" {
|
||||
z.Host += ":9000"
|
||||
}
|
||||
|
||||
// add parameters
|
||||
q := z.Query()
|
||||
if u.User != nil {
|
||||
if user := u.User.Username(); len(user) > 0 {
|
||||
q.Set("username", user)
|
||||
}
|
||||
if pass, ok := u.User.Password(); ok {
|
||||
q.Set("password", pass)
|
||||
}
|
||||
}
|
||||
z.RawQuery = q.Encode()
|
||||
|
||||
return z.String(), nil
|
||||
}
|
||||
|
||||
// GenVoltDB generates a VoltDB DSN from the passed URL.
|
||||
func GenVoltDB(u *URL) (string, error) {
|
||||
host, port := "localhost", "21212"
|
||||
if h := hostname(u.Host); h != "" {
|
||||
host = h
|
||||
}
|
||||
if p := hostport(u.Host); p != "" {
|
||||
port = p
|
||||
}
|
||||
return host + ":" + port, nil
|
||||
}
|
||||
|
||||
// GenPresto generates a Presto DSN from the passed URL.
|
||||
func GenPresto(u *URL) (string, error) {
|
||||
z := &url.URL{
|
||||
Scheme: "http",
|
||||
Opaque: u.Opaque,
|
||||
User: u.User,
|
||||
Host: u.Host,
|
||||
RawQuery: u.RawQuery,
|
||||
Fragment: u.Fragment,
|
||||
}
|
||||
|
||||
// change to https
|
||||
if strings.HasSuffix(u.OriginalScheme, "s") {
|
||||
z.Scheme = "https"
|
||||
}
|
||||
|
||||
// force user
|
||||
if z.User == nil {
|
||||
z.User = url.User("user")
|
||||
}
|
||||
|
||||
// force host
|
||||
if z.Host == "" {
|
||||
z.Host = "localhost"
|
||||
}
|
||||
|
||||
// force port
|
||||
if hostport(z.Host) == "" {
|
||||
if z.Scheme == "http" {
|
||||
z.Host += ":8080"
|
||||
} else if z.Scheme == "https" {
|
||||
z.Host += ":8443"
|
||||
}
|
||||
}
|
||||
|
||||
// add parameters
|
||||
q := z.Query()
|
||||
dbname, schema := strings.TrimPrefix(u.Path, "/"), ""
|
||||
if dbname == "" {
|
||||
dbname = "default"
|
||||
} else if i := strings.Index(dbname, "/"); i != -1 {
|
||||
schema, dbname = dbname[i+1:], dbname[:i]
|
||||
}
|
||||
q.Set("catalog", dbname)
|
||||
if schema != "" {
|
||||
q.Set("schema", schema)
|
||||
}
|
||||
z.RawQuery = q.Encode()
|
||||
|
||||
return z.String(), nil
|
||||
}
|
||||
|
||||
// GenCassandra generates a cassandra DSN from the passed URL.
|
||||
func GenCassandra(u *URL) (string, error) {
|
||||
host, port, dbname := "localhost", "9042", strings.TrimPrefix(u.Path, "/")
|
||||
if h := hostname(u.Host); h != "" {
|
||||
host = h
|
||||
}
|
||||
if p := hostport(u.Host); p != "" {
|
||||
port = p
|
||||
}
|
||||
q := u.Query()
|
||||
// add user/pass
|
||||
if u.User != nil {
|
||||
q.Set("username", u.User.Username())
|
||||
if pass, _ := u.User.Password(); pass != "" {
|
||||
q.Set("password", pass)
|
||||
}
|
||||
}
|
||||
// add dbname
|
||||
if dbname != "" {
|
||||
q.Set("keyspace", dbname)
|
||||
}
|
||||
return host + ":" + port + genQueryOptions(q), nil
|
||||
}
|
||||
|
||||
// GenIgnite generates an ignite DSN from the passed URL.
|
||||
func GenIgnite(u *URL) (string, error) {
|
||||
host, port, dbname := "localhost", "10800", strings.TrimPrefix(u.Path, "/")
|
||||
if h := hostname(u.Host); h != "" {
|
||||
host = h
|
||||
}
|
||||
if p := hostport(u.Host); p != "" {
|
||||
port = p
|
||||
}
|
||||
q := u.Query()
|
||||
// add user/pass
|
||||
if u.User != nil {
|
||||
q.Set("username", u.User.Username())
|
||||
if pass, _ := u.User.Password(); pass != "" {
|
||||
q.Set("password", pass)
|
||||
}
|
||||
}
|
||||
// add dbname
|
||||
if dbname != "" {
|
||||
dbname = "/" + dbname
|
||||
}
|
||||
return "tcp://" + host + ":" + port + dbname + genQueryOptions(q), nil
|
||||
}
|
||||
|
||||
// GenSnowflake generates a snowflake DSN from the passed URL.
|
||||
func GenSnowflake(u *URL) (string, error) {
|
||||
host, port, dbname := hostname(u.Host), hostport(u.Host), strings.TrimPrefix(u.Path, "/")
|
||||
if host == "" {
|
||||
return "", ErrMissingHost
|
||||
}
|
||||
if dbname == "" {
|
||||
return "", ErrMissingPath
|
||||
}
|
||||
if port != "" {
|
||||
port = ":" + port
|
||||
}
|
||||
|
||||
// add user/pass
|
||||
var user string
|
||||
if u.User != nil {
|
||||
user = u.User.Username()
|
||||
if pass, _ := u.User.Password(); pass != "" {
|
||||
user += ":" + pass
|
||||
}
|
||||
user += "@"
|
||||
}
|
||||
|
||||
return user + host + port + "/" + dbname + genQueryOptions(u.Query()), nil
|
||||
}
|
Reference in New Issue
Block a user