| 1 | module mssql |
| 2 | |
| 3 | @[params] |
| 4 | pub struct Config { |
| 5 | pub: |
| 6 | conn_str string |
| 7 | dsn string |
| 8 | driver string |
| 9 | server string |
| 10 | port int |
| 11 | uid string |
| 12 | user string |
| 13 | pwd string |
| 14 | password string |
| 15 | // if dbname empty, conn str will not contain Database info, |
| 16 | // and it is up to the server to choose which db to connect to. |
| 17 | dbname string |
| 18 | options map[string]string |
| 19 | } |
| 20 | |
| 21 | // connect creates a new connection using the provided configuration. |
| 22 | pub fn connect(config Config) !Connection { |
| 23 | return open(config.get_conn_str()) |
| 24 | } |
| 25 | |
| 26 | // open creates a new connection using a raw ODBC connection string. |
| 27 | pub fn open(conn_str string) !Connection { |
| 28 | mut conn := Connection{} |
| 29 | conn.connect(conn_str)! |
| 30 | return conn |
| 31 | } |
| 32 | |
| 33 | fn preferred_value(primary string, fallback string) string { |
| 34 | if primary != '' { |
| 35 | return primary |
| 36 | } |
| 37 | return fallback |
| 38 | } |
| 39 | |
| 40 | fn needs_odbc_braces(value string) bool { |
| 41 | return value.contains_any(' \t\r\n;{}') |
| 42 | } |
| 43 | |
| 44 | fn format_odbc_value(value string) string { |
| 45 | if value == '' { |
| 46 | return '' |
| 47 | } |
| 48 | if needs_odbc_braces(value) { |
| 49 | return '{' + value.replace('}', '}}') + '}' |
| 50 | } |
| 51 | return value |
| 52 | } |
| 53 | |
| 54 | fn append_conn_part(mut parts []string, key string, value string) { |
| 55 | if value == '' { |
| 56 | return |
| 57 | } |
| 58 | parts << '${key}=${format_odbc_value(value)}' |
| 59 | } |
| 60 | |
| 61 | // get_conn_str builds an ODBC connection string from the configured fields. |
| 62 | pub fn (cfg Config) get_conn_str() string { |
| 63 | if cfg.conn_str != '' { |
| 64 | return cfg.conn_str |
| 65 | } |
| 66 | mut parts := []string{} |
| 67 | append_conn_part(mut parts, 'DSN', cfg.dsn) |
| 68 | append_conn_part(mut parts, 'Driver', cfg.driver) |
| 69 | append_conn_part(mut parts, 'Server', cfg.server) |
| 70 | if cfg.port > 0 { |
| 71 | parts << 'Port=${cfg.port}' |
| 72 | } |
| 73 | append_conn_part(mut parts, 'UID', preferred_value(cfg.uid, cfg.user)) |
| 74 | append_conn_part(mut parts, 'PWD', preferred_value(cfg.pwd, cfg.password)) |
| 75 | if cfg.dbname != '' { |
| 76 | append_conn_part(mut parts, 'Database', cfg.dbname) |
| 77 | } |
| 78 | if cfg.options.len > 0 { |
| 79 | mut option_keys := cfg.options.keys() |
| 80 | option_keys.sort() |
| 81 | for key in option_keys { |
| 82 | append_conn_part(mut parts, key, cfg.options[key]) |
| 83 | } |
| 84 | } |
| 85 | return parts.join(';') |
| 86 | } |
| 87 | |