Documentation
¶
Overview ¶
Package config provides unified configuration management for GoSQLX across CLI, LSP server, and IDE integrations. It supports loading from multiple sources with a layered priority system, including configuration files (YAML/JSON), environment variables, and LSP initialization options.
Configuration Architecture ¶
The config package implements a flexible, multi-source configuration system with:
- File-based configuration (YAML, JSON) with multiple search paths
- Environment variable overrides with GOSQLX_ prefix
- LSP initialization options for IDE integration
- Intelligent merging with proper precedence handling
- Thread-safe caching with automatic invalidation
- Comprehensive validation with detailed error messages
Configuration Sources ¶
Configurations can be loaded from multiple sources in order of precedence (highest to lowest):
- CLI flags (handled by cmd/gosqlx)
- Environment variables (GOSQLX_*)
- Configuration files (.gosqlx.yaml, gosqlx.json, etc.)
- Default values
Supported Configuration Sections ¶
Format: SQL formatting and output styling
- indent: Number of spaces for indentation (default: 2)
- uppercase_keywords: Convert SQL keywords to uppercase (default: true)
- max_line_length: Maximum line length before wrapping (default: 120)
- compact: Use compact formatting (default: false)
Validation: SQL validation and dialect settings
- dialect: Target SQL dialect - postgresql, mysql, sqlserver, oracle, sqlite (default: postgresql)
- strict_mode: Enable strict validation mode (default: false)
- recursive: Recursively validate files in directories (default: false)
- pattern: File pattern for recursive validation (default: "*.sql")
- security.max_file_size: Maximum file size in bytes (default: 10MB)
Output: Output formatting options
- format: Output format - text, json, yaml (default: text)
- verbose: Enable verbose output (default: false)
Analyze: SQL analysis settings
- security: Enable security analysis (default: false)
- performance: Enable performance analysis (default: false)
- complexity: Enable complexity analysis (default: false)
- all: Enable all analysis types (default: false)
LSP: Language Server Protocol settings
- rate_limit_requests: Max requests per window (default: 100)
- rate_limit_window: Rate limit time window (default: 1s)
- request_timeout: Request timeout (default: 30s)
- max_document_size: Max document size in bytes (default: 1MB)
- max_content_length: Max content length (default: 10MB)
- trace_server: LSP trace level - off, messages, verbose (default: off)
Server: General server settings
- log_level: Log level - debug, info, warn, error (default: info)
- log_file: Log file path (default: stderr)
- metrics_enabled: Enable metrics collection (default: true)
- shutdown_timeout: Graceful shutdown timeout (default: 5s)
Basic Usage ¶
Loading configuration from a file:
config, err := config.LoadFromFile("gosqlx.yaml")
if err != nil {
log.Fatal(err)
}
Loading with defaults and environment variables:
config, err := config.LoadWithDefaults("", true)
if err != nil {
log.Fatal(err)
}
Multi-Source Configuration ¶
Loading from multiple sources with proper precedence:
// Create base configuration
defaults := config.DefaultConfig()
// Load from file (if exists)
fileConfig, _ := config.LoadFromFile("gosqlx.yaml")
// Load from environment
envConfig, _ := config.LoadFromEnvironment("GOSQLX")
// Merge configurations (later sources override earlier)
merged := config.Merge(defaults, fileConfig, envConfig)
Configuration Files ¶
YAML format (.gosqlx.yaml):
format:
indent: 4
uppercase_keywords: true
max_line_length: 100
validation:
dialect: postgresql
strict_mode: false
security:
max_file_size: 10485760
lsp:
trace_server: messages
request_timeout: 30s
server:
log_level: info
metrics_enabled: true
JSON format (gosqlx.json):
{
"format": {
"indent": 4,
"uppercaseKeywords": true
},
"validation": {
"dialect": "postgresql"
}
}
Environment Variables ¶
All configuration options can be set via environment variables using the GOSQLX_ prefix:
export GOSQLX_FORMAT_INDENT=4 export GOSQLX_FORMAT_UPPERCASE_KEYWORDS=true export GOSQLX_VALIDATION_DIALECT=postgresql export GOSQLX_LSP_TRACE_SERVER=messages export GOSQLX_SERVER_LOG_LEVEL=debug
Boolean values accept: true, false, 1, 0, t, f, T, F Duration values accept: 30s, 5m, 1h, etc.
LSP Integration ¶
Loading from LSP initialization options:
config, err := config.LoadFromLSPInitOptions(initOptions)
if err != nil {
log.Fatal(err)
}
Converting to LSP settings format:
settings := config.ToLSPSettings(myConfig) // Returns map suitable for VSCode settings.json
Merging LSP configuration changes:
updated, err := config.MergeLSPConfig(currentConfig, changes)
if err != nil {
log.Fatal(err)
}
Configuration Caching ¶
The package includes built-in caching for file-based configurations with automatic invalidation based on file modification times:
// Cached loading (recommended for repeated access)
config, err := config.LoadFromFileCached("gosqlx.yaml")
// Clear cache (useful after config changes)
config.ClearConfigCache()
// Invalidate specific file
config.InvalidateConfigCache("gosqlx.yaml")
// Get cache statistics
stats := config.GetConfigCacheStats()
fmt.Printf("Cache hit rate: %.2f%%\n", stats.HitRate * 100)
Cache characteristics:
- Thread-safe operations with RWMutex
- Automatic invalidation on file modification
- TTL-based expiration (default: 5 minutes)
- LRU-style eviction when max size reached
- Atomic metrics tracking (hits, misses, evictions)
Configuration Search Paths ¶
Default search paths (in order of precedence):
- ./gosqlx.yaml
- ./gosqlx.yml
- ./gosqlx.json
- ./.gosqlx.yaml
- ./.gosqlx.yml
- ~/.config/gosqlx/config.yaml
- ~/.config/gosqlx/config.yml
- ~/.config/gosqlx/config.json
- /etc/gosqlx/config.yaml
- /etc/gosqlx/config.yml
- /etc/gosqlx/config.json
Loading from search paths:
paths := config.GetDefaultConfigPaths()
cfg, err := config.LoadFromFiles(paths)
if err != nil {
// No config file found in any location
cfg = config.DefaultConfig()
}
Validation ¶
All loaded configurations are automatically validated:
config := config.DefaultConfig() config.Format.Indent = -1 // Invalid value err := config.Validate() // err: "format.indent must be non-negative, got -1"
Validation checks:
- Format: Non-negative indent and max_line_length
- Validation: Valid dialect (postgresql, mysql, sqlserver, oracle, sqlite)
- Output: Valid format (text, json, yaml)
- LSP: Non-negative rate limits, timeouts, and size limits
- LSP: Valid trace server level (off, messages, verbose)
- Server: Valid log level (debug, info, warn, error)
- Server: Non-negative shutdown timeout
Helper Functions ¶
The package provides helper functions for working with boolean pointers:
// Create bool pointer ptr := config.Bool(true) // Get bool value with default value := config.BoolValue(ptr) // Returns false if nil // Get bool value with custom default value := config.BoolValueOr(ptr, true) // Returns true if nil
These helpers distinguish between "not set" (nil) and "explicitly set to false".
Thread Safety ¶
The config package is designed for concurrent use:
- All exported functions are safe for concurrent calls
- Config caching uses sync.RWMutex for thread-safe access
- Metrics use atomic operations for lock-free updates
- Immutable Config objects after loading (use Clone() for modifications)
Performance Considerations ¶
Configuration loading performance characteristics:
- File loading: I/O bound, uses caching for repeated access
- Environment loading: Fast, reads environment once
- LSP loading: Fast, JSON marshaling/unmarshaling overhead
- Merging: Fast, linear in number of config sections
- Validation: Fast, constant time checks
Recommended practices:
- Use LoadFromFileCached() for repeated file access
- Load configuration once at startup, reuse throughout application
- Use Clone() when creating modified configurations
- Monitor cache hit rate with GetConfigCacheStats()
Example: Complete CLI Integration ¶
package main
import (
"flag"
"log"
"github.com/ajitpratap0/GoSQLX/pkg/config"
)
func main() {
configFile := flag.String("config", "", "Configuration file path")
dialect := flag.String("dialect", "", "SQL dialect override")
flag.Parse()
// Load configuration with defaults
cfg, err := config.LoadWithDefaults(*configFile, true)
if err != nil {
log.Fatal(err)
}
// Apply CLI flag overrides
if *dialect != "" {
cfg.Validation.Dialect = *dialect
if err := cfg.Validate(); err != nil {
log.Fatal(err)
}
}
// Use configuration
log.Printf("Using dialect: %s", cfg.Validation.Dialect)
log.Printf("Indent: %d spaces", cfg.Format.Indent)
}
Example: LSP Server Integration ¶
package main
import (
"log"
"github.com/ajitpratap0/GoSQLX/pkg/config"
)
func handleInitialize(initOptions interface{}) {
// Load base configuration
baseConfig, _ := config.LoadWithDefaults("", true)
// Merge LSP initialization options
cfg, err := config.MergeLSPConfig(baseConfig, initOptions)
if err != nil {
log.Printf("Invalid LSP config: %v", err)
cfg = baseConfig
}
// Configure LSP server with merged settings
startLSPServer(cfg)
}
func handleConfigChange(changes interface{}) {
// Merge configuration changes
cfg, err := config.MergeLSPConfig(currentConfig, changes)
if err != nil {
log.Printf("Invalid config change: %v", err)
return
}
// Apply new configuration
updateConfiguration(cfg)
}
Version History ¶
v1.6.0: Initial release with unified configuration system
- File-based configuration (YAML/JSON)
- Environment variable support
- LSP integration
- Thread-safe caching
- Comprehensive validation
See Also ¶
- docs/CONFIGURATION.md - Complete configuration guide
- docs/LSP_GUIDE.md - LSP server configuration
- cmd/gosqlx - CLI tool using this package
- pkg/lsp - LSP server using this package
Index ¶
- func Bool(v bool) *bool
- func BoolValue(p *bool) bool
- func BoolValueOr(p *bool, defaultVal bool) bool
- func ClearConfigCache()
- func ConfigCacheSize() int
- func GetDefaultConfigPaths() []string
- func InvalidateConfigCache(path string)
- func ResetConfigCacheStats()
- func ToLSPInitializationOptions(c *Config) map[string]interface{}
- func ToLSPSettings(c *Config) map[string]interface{}
- func ValidateLSPValue(section, key string, value interface{}) error
- type AnalyzeConfig
- type Config
- func DefaultConfig() *Config
- func FromLSPSettings(settings map[string]interface{}) (*Config, error)
- func LoadFromEnvironment(prefix string) (*Config, error)
- func LoadFromFile(path string) (*Config, error)
- func LoadFromFileCached(path string) (*Config, error)
- func LoadFromFiles(searchPaths []string) (*Config, error)
- func LoadFromLSPInitOptions(opts interface{}) (*Config, error)
- func LoadWithDefaults(configFile string, useEnv bool) (*Config, error)
- func Merge(configs ...*Config) *Config
- func MergeLSPConfig(base *Config, changes interface{}) (*Config, error)
- type ConfigCacheStats
- type FormatConfig
- type LSPConfig
- type LSPConfigSection
- type OutputConfig
- type SecurityConfig
- type ServerConfig
- type ValidationConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Bool ¶
Bool returns a pointer to the given bool value. Use this helper when setting boolean config values.
func BoolValueOr ¶
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 ¶
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 ¶
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 ¶
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 for SQL query analysis.
Each boolean field enables a specific type of analysis:
- Security: SQL injection detection and security pattern scanning
- Performance: Query performance hints and optimization suggestions
- Complexity: Query complexity metrics and readability analysis
- All: Enables all analysis types at once
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.
Config objects are designed to be immutable after loading. Use Clone() to create a copy before making modifications. All configuration sections use pointer types for boolean fields to distinguish between "not set" (nil) and "explicitly false".
The Source field tracks where the configuration was loaded from, which is useful for debugging and logging. When configurations are merged, the Source field combines all sources (e.g., "default+file+environment").
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a configuration with sensible default values
func FromLSPSettings ¶
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 ¶
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 ¶
LoadFromFile loads configuration from a single file. Supports both YAML and JSON formats based on file extension.
func LoadFromFileCached ¶
LoadFromFileCached loads configuration from a file with caching. If the file hasn't changed since the last load, returns the cached version.
func LoadFromFiles ¶
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 ¶
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 ¶
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 ¶
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 ¶
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
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 for the formatter.
Boolean fields use *bool pointers to distinguish between "not set" (nil) and "explicitly set to false". This allows proper override behavior when merging configurations from multiple sources.
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 for the Language Server Protocol server.
Rate limiting prevents denial-of-service from excessive requests. Requests are limited to RateLimitRequests per RateLimitWindow duration.
Size limits prevent memory exhaustion from large documents. MaxDocumentSize limits the size of individual SQL files, while MaxContentLength limits the total size of all content in a single LSP request.
TraceServer controls LSP protocol tracing: "off" (default), "messages" (log messages), or "verbose" (log messages with full content).
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 for CLI and LSP responses.
The Format field determines the output format for validation results, analysis reports, and other tool outputs. Supported values: "text", "json", "yaml".
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 for file size limits and other security-related constraints.
MaxFileSize prevents processing of excessively large files that could cause memory exhaustion. The default is 10MB (10 * 1024 * 1024 bytes).
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 for logging, metrics, and lifecycle management.
LogLevel determines the verbosity of logging: "debug", "info", "warn", "error". LogFile specifies where to write logs; empty string means stderr.
ShutdownTimeout controls how long the server waits for graceful shutdown before forcefully terminating. This allows in-flight requests to complete.
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 for the parser and validator.
The Dialect field determines which SQL keywords and syntax are recognized. Supported values: "postgresql", "mysql", "sqlserver", "oracle", "sqlite".
The Pattern field is used for recursive file validation and supports standard glob patterns like "*.sql", "queries/**/*.sql", etc.