ParseDSN parses the DSN string to a Config
(dsn string)
| 394 | |
| 395 | // ParseDSN parses the DSN string to a Config |
| 396 | func ParseDSN(dsn string) (cfg *Config, err error) { |
| 397 | // New config with some default values |
| 398 | cfg = NewConfig() |
| 399 | |
| 400 | // [user[:password]@][net[(addr)]]/dbname[?param1=value1¶mN=valueN] |
| 401 | // Find the last '/' (since the password or the net addr might contain a '/') |
| 402 | foundSlash := false |
| 403 | for i := len(dsn) - 1; i >= 0; i-- { |
| 404 | if dsn[i] == '/' { |
| 405 | foundSlash = true |
| 406 | var j, k int |
| 407 | |
| 408 | // left part is empty if i <= 0 |
| 409 | if i > 0 { |
| 410 | // [username[:password]@][protocol[(address)]] |
| 411 | // Find the last '@' in dsn[:i] |
| 412 | for j = i; j >= 0; j-- { |
| 413 | if dsn[j] == '@' { |
| 414 | // username[:password] |
| 415 | // Find the first ':' in dsn[:j] |
| 416 | for k = 0; k < j; k++ { // We cannot use k = range j here, because we use dsn[:k] below |
| 417 | if dsn[k] == ':' { |
| 418 | cfg.Passwd = dsn[k+1 : j] |
| 419 | break |
| 420 | } |
| 421 | } |
| 422 | cfg.User = dsn[:k] |
| 423 | |
| 424 | break |
| 425 | } |
| 426 | } |
| 427 | |
| 428 | // [protocol[(address)]] |
| 429 | // Find the first '(' in dsn[j+1:i] |
| 430 | for k = j + 1; k < i; k++ { |
| 431 | if dsn[k] == '(' { |
| 432 | // dsn[i-1] must be == ')' if an address is specified |
| 433 | if dsn[i-1] != ')' { |
| 434 | if strings.ContainsRune(dsn[k+1:i], ')') { |
| 435 | return nil, errInvalidDSNUnescaped |
| 436 | } |
| 437 | return nil, errInvalidDSNAddr |
| 438 | } |
| 439 | cfg.Addr = dsn[k+1 : i-1] |
| 440 | break |
| 441 | } |
| 442 | } |
| 443 | cfg.Net = dsn[j+1 : k] |
| 444 | } |
| 445 | |
| 446 | // dbname[?param1=value1&...¶mN=valueN] |
| 447 | // Find the first '?' in dsn[i+1:] |
| 448 | for j = i + 1; j < len(dsn); j++ { |
| 449 | if dsn[j] == '?' { |
| 450 | if err = parseDSNParams(cfg, dsn[j+1:]); err != nil { |
| 451 | return |
| 452 | } |
| 453 | break |