helpers.go 3.8 KB

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