-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathhelpers.go
148 lines (130 loc) · 3.74 KB
/
helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package simplemaria
import (
"log"
"strconv"
"strings"
)
var Verbose = false
/* --- Helper functions --- */
// Split a string into two parts, given a delimiter.
// Returns the two parts and true if it works out.
func twoFields(s, delim string) (string, string, bool) {
if strings.Count(s, delim) != 1 {
return s, "", false
}
fields := strings.Split(s, delim)
return fields[0], fields[1], true
}
func leftOf(s, delim string) string {
if left, _, ok := twoFields(s, delim); ok {
return strings.TrimSpace(left)
}
return ""
}
func rightOf(s, delim string) string {
if _, right, ok := twoFields(s, delim); ok {
return strings.TrimSpace(right)
}
return ""
}
// Parse a DSN
func splitConnectionString(connectionString string) (string, string, bool, string, string, string) {
var (
userPass, hostPortDatabase, dbname string
hostPort, password, username, port, host string
hasPassword bool
)
// Gather the fields
// Optional left side of @ with username and password
userPass = leftOf(connectionString, "@")
if userPass != "" {
hostPortDatabase = rightOf(connectionString, "@")
} else {
if strings.HasSuffix(connectionString, "@") {
hostPortDatabase = connectionString[:len(connectionString)-1]
} else {
hostPortDatabase = connectionString
}
}
// Optional right side of / with database name
dbname = rightOf(hostPortDatabase, "/")
if dbname != "" {
hostPort = leftOf(hostPortDatabase, "/")
} else {
if strings.HasSuffix(hostPortDatabase, "/") {
hostPort = hostPortDatabase[:len(hostPortDatabase)-1]
} else {
hostPort = hostPortDatabase
}
dbname = defaultDatabaseName
}
// Optional right side of : with password
password = rightOf(userPass, ":")
if password != "" {
username = leftOf(userPass, ":")
} else {
if strings.HasSuffix(userPass, ":") {
username = userPass[:len(userPass)-1]
hasPassword = true
} else {
username = userPass
}
}
// Optional right side of : with port
port = rightOf(hostPort, ":")
if port != "" {
host = leftOf(hostPort, ":")
} else {
if strings.HasSuffix(hostPort, ":") {
host = hostPort[:len(hostPort)-1]
} else {
host = hostPort
}
if host != "" {
port = strconv.Itoa(defaultPort)
}
}
if Verbose {
log.Println("Connection:")
log.Println("\tusername:\t", username)
log.Println("\tpassword:\t", password)
log.Println("\thas password:\t", hasPassword)
log.Println("\thost:\t\t", host)
log.Println("\tport:\t\t", port)
log.Println("\tdbname:\t\t", dbname)
log.Println()
}
return username, password, hasPassword, host, port, dbname
}
func buildConnectionString(username, password string, hasPassword bool, host, port, dbname string) string {
// Build the new connection string without "tcp()"
var newConnectionString string
if username != "" {
if hasPassword {
newConnectionString = username + ":" + password
} else {
newConnectionString = username
}
newConnectionString += "@" // Include '@' only if there's a username
}
if host != "" && port != "" {
newConnectionString += host + ":" + port
} else if host != "" {
newConnectionString += host
} else if port != "" {
// Only having a port is unusual and generally not recommended
log.Fatalln("Only a port is specified without a host, which is invalid.")
}
if dbname != "" {
newConnectionString += "/" + dbname
}
if Verbose {
log.Println("DSN:", newConnectionString)
}
return newConnectionString
}
// Take apart and rebuild the connection string. Also return the dbname.
func rebuildConnectionString(connectionString string) (string, string) {
username, password, hasPassword, hostname, port, dbname := splitConnectionString(connectionString)
return buildConnectionString(username, password, hasPassword, hostname, port, dbname), dbname
}