config.go•3.61 kB
package mssql
import (
_ "embed"
"fmt"
"gopkg.in/yaml.v3"
)
//go:embed readme.md
var docString string
// Config represents the configuration for a Microsoft SQL Server connection
type Config struct {
Hosts []string `json:"hosts" yaml:"hosts"` // List of server addresses
User string `json:"user" yaml:"user"` // Username for authentication
Password string `json:"password" yaml:"password"` // Password for authentication
Database string `json:"database" yaml:"database"` // Database name
Port int `json:"port" yaml:"port"` // Port number (default 1433)
Schema string `json:"schema" yaml:"schema"` // Schema name (default "dbo")
ConnString string `json:"conn_string" yaml:"conn_string"` // Direct connection string
IsReadonly bool `json:"is_readonly" yaml:"is_readonly"`
}
func (c Config) Readonly() bool {
return c.IsReadonly
}
// UnmarshalYAML implements the yaml.Unmarshaler interface to allow for both
// direct connection string or full configuration objects in YAML
func (c *Config) UnmarshalYAML(value *yaml.Node) error {
// Try to unmarshal as a string (connection string)
var connString string
if err := value.Decode(&connString); err == nil && len(connString) > 0 {
c.ConnString = connString
return nil
}
// If that didn't work, try to unmarshal as a full config object
type configAlias Config // Use alias to avoid infinite recursion
var alias configAlias
if err := value.Decode(&alias); err != nil {
return err
}
*c = Config(alias)
return nil
}
// ConnectionString generates a connection string for Microsoft SQL Server
func (c Config) ConnectionString() string {
// If direct connection string is provided, use it
if c.ConnString != "" {
return c.ConnString
}
// Use the first host from the list
server := c.Hosts[0]
if len(c.Hosts) > 1 {
// If multiple hosts are provided, we could implement failover here
// For now, just use the first one
}
// Build connection string using DSN format with explicit options
// This format is more reliable for handling special characters in passwords
connStr := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;TrustServerCertificate=true",
server,
c.User,
c.Password,
c.Port,
c.Database)
// Add schema if specified
if c.Schema != "" {
connStr += fmt.Sprintf(";defaultSchema=%s", c.Schema)
}
return connStr
}
// Validate checks if the configuration is valid
func (c Config) Validate() error {
if len(c.Hosts) == 0 {
return fmt.Errorf("at least one server address is required")
}
if c.Database == "" {
return fmt.Errorf("database name is required")
}
if c.User == "" {
return fmt.Errorf("username is required")
}
if c.Password == "" {
return fmt.Errorf("password is required")
}
if c.Port == 0 {
c.Port = 1433 // Set default port if not specified
}
return nil
}
// Type returns the type of the connector
func (c Config) Type() string {
return "mssql"
}
// Doc returns documentation about the configuration
func (c Config) Doc() string {
return `Microsoft SQL Server connection configuration:
hosts: List of server addresses (e.g., ["localhost", "backup-server"])
user: Username for authentication
password: Password for authentication
database: Database name
port: Port number (default: 1433)
schema: Schema name (default: "dbo")`
}
// ExtraPrompt returns additional prompt information for the configuration
func (c Config) ExtraPrompt() []string {
return []string{
"Use symbol ':' instead of '@' for named parameters in sql query",
}
}