config

package
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 11, 2025 License: AGPL-3.0 Imports: 12 Imported by: 0

README

Config Package

Unified configuration management for GoSQLX that can be shared across CLI, LSP server, and VSCode extension.

Features

  • Multiple Sources: Load configuration from files (YAML/JSON), environment variables, and LSP initialization options
  • Layered Configuration: Merge configurations with proper precedence (defaults → file → environment → LSP/CLI flags)
  • Validation: Comprehensive validation for all configuration options
  • LSP Integration: First-class support for Language Server Protocol configuration exchange
  • Type Safety: Strongly-typed configuration with sensible defaults

Usage

Loading from Files
import "github.com/ajitpratap0/GoSQLX/pkg/config"

// Load from single file
cfg, err := config.LoadFromFile("gosqlx.yaml")
if err != nil {
    log.Fatal(err)
}

// Try multiple paths in order
cfg, err := config.LoadFromFiles([]string{
    "./gosqlx.yaml",
    "~/.config/gosqlx/config.yaml",
    "/etc/gosqlx/config.yaml",
})

// Get default search paths
paths := config.GetDefaultConfigPaths()
cfg, err := config.LoadFromFiles(paths)
Loading from Environment Variables
// Load from environment (GOSQLX_* variables)
cfg, err := config.LoadFromEnvironment("GOSQLX")

// Custom prefix
cfg, err := config.LoadFromEnvironment("MYAPP")

Environment variable names follow the pattern: PREFIX_SECTION_FIELD

Examples:

  • GOSQLX_FORMAT_INDENT=4
  • GOSQLX_VALIDATION_DIALECT=postgresql
  • GOSQLX_LSP_TRACE_SERVER=verbose
Layered Configuration
// Load with automatic layering: defaults → file → environment
cfg, err := config.LoadWithDefaults("gosqlx.yaml", true)

// Manual merging for custom scenarios
defaultCfg := config.DefaultConfig()
fileCfg, _ := config.LoadFromFile("config.yaml")
envCfg, _ := config.LoadFromEnvironment("GOSQLX")

// Later configs override earlier ones
merged := config.Merge(defaultCfg, fileCfg, envCfg)
LSP Integration
// Load from LSP initialization options
cfg, err := config.LoadFromLSPInitOptions(initOptions)

// Convert to LSP settings format for VSCode
settings := config.ToLSPSettings(cfg)

// Parse from VSCode settings.json format
cfg, err := config.FromLSPSettings(settings)

// Merge LSP configuration changes
updated, err := config.MergeLSPConfig(baseCfg, changes)

// Get initialization options for LSP client
initOpts := config.ToLSPInitializationOptions(cfg)

Configuration Structure

Format Settings
format:
  indent: 2                    # Indentation spaces
  uppercase_keywords: true     # Convert SQL keywords to uppercase
  max_line_length: 120        # Maximum line length
  compact: false              # Use compact formatting
Validation Settings
validation:
  dialect: postgresql         # SQL dialect (postgresql, mysql, sqlserver, oracle, sqlite)
  strict_mode: false          # Enable strict validation
  recursive: false            # Recursively validate directories
  pattern: "*.sql"            # File pattern for validation
  security:
    max_file_size: 10485760   # Maximum file size (10MB)
Output Settings
output:
  format: text               # Output format (text, json, yaml)
  verbose: false             # Enable verbose output
Analysis Settings
analyze:
  security: false            # Enable security analysis
  performance: false         # Enable performance analysis
  complexity: false          # Enable complexity analysis
  all: false                 # Enable all analysis types
LSP Settings
lsp:
  rate_limit_requests: 100   # Max requests per window
  rate_limit_window: 1s      # Rate limit time window
  request_timeout: 30s       # Request timeout
  max_document_size: 1048576 # Max document size (1MB)
  max_content_length: 10485760 # Max content length (10MB)
  trace_server: off          # LSP trace level (off, messages, verbose)
Server Settings
server:
  log_level: info            # Log level (debug, info, warn, error)
  log_file: ""               # Log file path (empty for stderr)
  metrics_enabled: true      # Enable metrics collection
  shutdown_timeout: 5s       # Graceful shutdown timeout

JSON Configuration Example

{
  "format": {
    "indent": 4,
    "uppercaseKeywords": true,
    "maxLineLength": 100
  },
  "validation": {
    "dialect": "mysql",
    "strictMode": true
  },
  "lsp": {
    "traceServer": "verbose"
  }
}

Validation

All configuration values are validated after loading:

cfg := config.DefaultConfig()
cfg.Format.Indent = -1  // Invalid

if err := cfg.Validate(); err != nil {
    log.Printf("Invalid config: %v", err)
}

Validation rules:

  • Format.Indent: Must be non-negative
  • Format.MaxLineLength: Must be non-negative
  • Validation.Dialect: Must be one of: postgresql, mysql, sqlserver, oracle, sqlite
  • Validation.Security.MaxFileSize: Must be non-negative
  • Output.Format: Must be one of: text, json, yaml
  • LSP.TraceServer: Must be one of: off, messages, verbose
  • Server.LogLevel: Must be one of: debug, info, warn, error

Testing

The package includes comprehensive tests with 78.6% coverage:

go test ./pkg/config/
go test -race ./pkg/config/   # With race detection
go test -cover ./pkg/config/  # With coverage report

Notes

Boolean Configuration Merging

When using environment variables or layered configuration, boolean values can only be set to true via override. Setting them to false via environment variables won't override a true value from a file or defaults. This is a limitation of the zero-value merge approach.

Workaround: Use file-based configuration for boolean false values.

Configuration Source Tracking

The Source field tracks where configuration was loaded from:

  • "default" - DefaultConfig()
  • "lsp" - LSP initialization options
  • "environment" - Environment variables
  • "/path/to/file.yaml" - File path
  • "default+file+environment" - Merged sources

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bool

func Bool(v bool) *bool

Bool returns a pointer to the given bool value. Use this helper when setting boolean config values.

func BoolValue

func BoolValue(p *bool) bool

BoolValue returns the value of a bool pointer, or false if nil.

func BoolValueOr

func BoolValueOr(p *bool, defaultVal bool) bool

BoolValueOr returns the value of a bool pointer, or the default if nil.

func ClearConfigCache

func ClearConfigCache()

ClearConfigCache clears the config file cache. Useful for testing or when configuration changes need to be reloaded.

func ConfigCacheSize

func ConfigCacheSize() int

ConfigCacheSize returns the current size of the config cache.

func GetDefaultConfigPaths

func GetDefaultConfigPaths() []string

GetDefaultConfigPaths returns common configuration file paths to search. The paths are returned in order of precedence (highest to lowest): 1. Current directory 2. User config directory (~/.config/gosqlx/) 3. System config directory (/etc/gosqlx/)

func InvalidateConfigCache

func InvalidateConfigCache(path string)

InvalidateConfigCache invalidates a specific config file in the cache.

func ResetConfigCacheStats

func ResetConfigCacheStats()

ResetConfigCacheStats resets the cache statistics counters. Useful for testing and monitoring.

func ToLSPInitializationOptions

func ToLSPInitializationOptions(c *Config) map[string]interface{}

ToLSPInitializationOptions creates a minimal initialization options object suitable for sending to an LSP server. This includes only the most commonly needed settings and excludes server-internal configuration.

func ToLSPSettings

func ToLSPSettings(c *Config) map[string]interface{}

ToLSPSettings converts a Config to VSCode settings format. This returns a map suitable for use in LSP configuration responses or for serializing to VSCode settings.json.

The returned map uses camelCase keys to match VSCode conventions.

func ValidateLSPValue

func ValidateLSPValue(section, key string, value interface{}) error

ValidateLSPValue validates a single configuration value for LSP. This is useful for providing real-time validation in the VSCode extension.

Types

type AnalyzeConfig

type AnalyzeConfig struct {
	Security    *bool `yaml:"security" json:"security"`       // Enable security analysis (default: false)
	Performance *bool `yaml:"performance" json:"performance"` // Enable performance analysis (default: false)
	Complexity  *bool `yaml:"complexity" json:"complexity"`   // Enable complexity analysis (default: false)
	All         *bool `yaml:"all" json:"all"`                 // Enable all analysis types (default: false)
}

AnalyzeConfig holds analysis options

type Config

type Config struct {
	Format     FormatConfig     `yaml:"format" json:"format"`
	Validation ValidationConfig `yaml:"validation" json:"validation"`
	Output     OutputConfig     `yaml:"output" json:"output"`
	Analyze    AnalyzeConfig    `yaml:"analyze" json:"analyze"`
	LSP        LSPConfig        `yaml:"lsp" json:"lsp"`
	Server     ServerConfig     `yaml:"server" json:"server"`
	Source     string           `yaml:"-" json:"-"` // where config came from (file path, "environment", "lsp", etc.)
}

Config represents unified GoSQLX configuration that can be shared across CLI, LSP server, and VSCode extension. It supports loading from files, environment variables, and LSP initialization options.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a configuration with sensible default values

func FromLSPSettings

func FromLSPSettings(settings map[string]interface{}) (*Config, error)

FromLSPSettings creates a Config from VSCode settings format. This is the inverse of ToLSPSettings and can parse settings from VSCode's settings.json or workspace configuration.

func LoadFromEnvironment

func LoadFromEnvironment(prefix string) (*Config, error)

LoadFromEnvironment loads configuration from environment variables. Variable names are prefixed with the given prefix (e.g., "GOSQLX_"). Nested fields use underscores: GOSQLX_FORMAT_INDENT, GOSQLX_LSP_REQUEST_TIMEOUT, etc. Only values explicitly set in environment variables are included in the returned config.

func LoadFromFile

func LoadFromFile(path string) (*Config, error)

LoadFromFile loads configuration from a single file. Supports both YAML and JSON formats based on file extension.

func LoadFromFileCached

func LoadFromFileCached(path string) (*Config, error)

LoadFromFileCached loads configuration from a file with caching. If the file hasn't changed since the last load, returns the cached version.

func LoadFromFiles

func LoadFromFiles(searchPaths []string) (*Config, error)

LoadFromFiles tries to load configuration from multiple paths in order. Returns the first successfully loaded configuration, or an error if none can be loaded. This is useful for searching common config locations like: - ./gosqlx.yaml - ~/.config/gosqlx/config.yaml - /etc/gosqlx/config.yaml

func LoadFromLSPInitOptions

func LoadFromLSPInitOptions(opts interface{}) (*Config, error)

LoadFromLSPInitOptions loads configuration from LSP initialization options. The opts parameter should be the initializationOptions field from the LSP initialize request, typically sent by the VSCode extension.

Example initializationOptions structure:

{
  "format": {
    "indent": 2,
    "uppercaseKeywords": true
  },
  "validation": {
    "dialect": "postgresql"
  }
}

func LoadWithDefaults

func LoadWithDefaults(configFile string, useEnv bool) (*Config, error)

LoadWithDefaults loads configuration from multiple sources with the following precedence: 1. Default configuration (lowest priority) 2. Configuration file (if provided and exists) 3. Environment variables (if enabled) The result is validated before being returned.

func Merge

func Merge(configs ...*Config) *Config

Merge merges multiple configurations, with later configs taking precedence over earlier ones. Zero values in later configs are ignored (won't override non-zero values from earlier configs). This allows layered configuration: defaults -> file -> environment -> CLI flags.

func MergeLSPConfig

func MergeLSPConfig(base *Config, changes interface{}) (*Config, error)

MergeLSPConfig merges LSP-specific configuration changes into an existing config. This is useful for handling workspace configuration changes in the LSP server. Only non-nil/non-zero values from changes are applied.

func (*Config) ApplyDefaults

func (c *Config) ApplyDefaults()

ApplyDefaults fills in any zero values with defaults

func (*Config) Clone

func (c *Config) Clone() *Config

Clone creates a deep copy of the configuration

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration and returns an error if any settings are invalid

type ConfigCacheStats

type ConfigCacheStats struct {
	Size      int
	MaxSize   int
	TTL       time.Duration
	Hits      uint64
	Misses    uint64
	Evictions uint64
	HitRate   float64
}

ConfigCacheStats holds cache statistics

func GetConfigCacheStats

func GetConfigCacheStats() ConfigCacheStats

GetConfigCacheStats returns current cache statistics

type FormatConfig

type FormatConfig struct {
	Indent            int   `yaml:"indent" json:"indent"`                        // Number of spaces for indentation (default: 2)
	UppercaseKeywords *bool `yaml:"uppercase_keywords" json:"uppercaseKeywords"` // Convert SQL keywords to uppercase (default: true)
	MaxLineLength     int   `yaml:"max_line_length" json:"maxLineLength"`        // Maximum line length before wrapping (default: 120)
	Compact           *bool `yaml:"compact" json:"compact"`                      // Use compact formatting (default: false)
}

FormatConfig holds SQL formatting options

type LSPConfig

type LSPConfig struct {
	RateLimitRequests int           `yaml:"rate_limit_requests" json:"rateLimitRequests"` // Max requests per window (default: 100)
	RateLimitWindow   time.Duration `yaml:"rate_limit_window" json:"rateLimitWindow"`     // Rate limit time window (default: 1s)
	RequestTimeout    time.Duration `yaml:"request_timeout" json:"requestTimeout"`        // Request timeout (default: 30s)
	MaxDocumentSize   int           `yaml:"max_document_size" json:"maxDocumentSize"`     // Max document size in bytes (default: 1MB)
	MaxContentLength  int           `yaml:"max_content_length" json:"maxContentLength"`   // Max content length (default: 10MB)
	TraceServer       string        `yaml:"trace_server" json:"traceServer"`              // LSP trace level: off, messages, verbose (default: "off")
}

LSPConfig holds LSP server-specific settings

type LSPConfigSection

type LSPConfigSection struct {
	Section      string                 `json:"section"`
	Properties   map[string]interface{} `json:"properties"`
	Description  string                 `json:"description,omitempty"`
	DefaultValue interface{}            `json:"defaultValue,omitempty"`
}

LSPConfigSection represents a section of LSP configuration that can be registered with the VSCode extension for dynamic configuration updates.

func GetLSPConfigSections

func GetLSPConfigSections() []LSPConfigSection

GetLSPConfigSections returns all configuration sections for registration with the LSP workspace/configuration capability. This allows the VSCode extension to provide configuration UI and validation.

type OutputConfig

type OutputConfig struct {
	Format  string `yaml:"format" json:"format"`   // Output format: text, json, yaml (default: "text")
	Verbose *bool  `yaml:"verbose" json:"verbose"` // Enable verbose output (default: false)
}

OutputConfig holds output formatting options

type SecurityConfig

type SecurityConfig struct {
	MaxFileSize int64 `yaml:"max_file_size" json:"maxFileSize"` // Maximum file size in bytes (default: 10MB)
}

SecurityConfig holds security validation settings

type ServerConfig

type ServerConfig struct {
	LogLevel        string        `yaml:"log_level" json:"logLevel"`               // Log level: debug, info, warn, error (default: "info")
	LogFile         string        `yaml:"log_file" json:"logFile"`                 // Log file path (default: "" for stderr)
	MetricsEnabled  *bool         `yaml:"metrics_enabled" json:"metricsEnabled"`   // Enable metrics collection (default: true)
	ShutdownTimeout time.Duration `yaml:"shutdown_timeout" json:"shutdownTimeout"` // Graceful shutdown timeout (default: 5s)
}

ServerConfig holds general server settings

type ValidationConfig

type ValidationConfig struct {
	Dialect    string         `yaml:"dialect" json:"dialect"`        // SQL dialect: postgresql, mysql, sqlserver, oracle, sqlite (default: "postgresql")
	StrictMode *bool          `yaml:"strict_mode" json:"strictMode"` // Enable strict validation mode (default: false)
	Recursive  *bool          `yaml:"recursive" json:"recursive"`    // Recursively validate files in directories (default: false)
	Pattern    string         `yaml:"pattern" json:"pattern"`        // File pattern for recursive validation (default: "*.sql")
	Security   SecurityConfig `yaml:"security" json:"security"`      // Security validation settings
}

ValidationConfig holds SQL validation options

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL