gosqlx

package
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2025 License: MIT Imports: 7 Imported by: 0

README

gosqlx - High-Level SQL Parsing API

Go Reference

The gosqlx package provides a convenient, high-level API for SQL parsing in GoSQLX. It wraps the lower-level tokenizer and parser APIs to provide a simple, ergonomic interface for common operations with automatic object pool management.

Quick Start

import "github.com/ajitpratap0/GoSQLX/pkg/gosqlx"

// Parse SQL in one line
ast, err := gosqlx.Parse("SELECT * FROM users WHERE active = true")
if err != nil {
    log.Fatal(err)
}

// Or just validate
if err := gosqlx.Validate("SELECT * FROM users"); err != nil {
    log.Fatal("Invalid SQL:", err)
}

Features

  • Simple API: Parse SQL with a single function call
  • Automatic Resource Management: Object pools handled internally
  • Batch Processing: Efficient parsing of multiple queries
  • Validation: Quick syntax validation without full AST construction
  • Format Support: Basic SQL formatting (with plans for advanced formatting)
  • Production Ready: Built on top of GoSQLX's production-tested parser

Installation

go get github.com/ajitpratap0/GoSQLX

API Reference

Core Functions
Parse

Parse SQL string into an Abstract Syntax Tree (AST):

func Parse(sql string) (*ast.AST, error)

Example:

ast, err := gosqlx.Parse("SELECT * FROM users")
if err != nil {
    return err
}

// Access parsed statements
for _, stmt := range ast.Statements {
    // Process each statement
}
ParseBytes

Parse SQL from a byte slice (useful for file I/O):

func ParseBytes(sql []byte) (*ast.AST, error)

Example:

sqlBytes := []byte("SELECT * FROM users")
ast, err := gosqlx.ParseBytes(sqlBytes)
Validate

Validate SQL syntax without building the full AST:

func Validate(sql string) error

Example:

if err := gosqlx.Validate(userInput); err != nil {
    return fmt.Errorf("invalid SQL: %w", err)
}
MustParse

Parse SQL or panic (useful for testing and initialization):

func MustParse(sql string) *ast.AST

Example:

// In tests or init functions
ast := gosqlx.MustParse("SELECT 1")
Batch Processing Functions
ParseMultiple

Parse multiple SQL statements efficiently by reusing parser resources:

func ParseMultiple(queries []string) ([]*ast.AST, error)

Example:

queries := []string{
    "SELECT * FROM users",
    "SELECT * FROM orders",
    "SELECT * FROM products",
}

asts, err := gosqlx.ParseMultiple(queries)
if err != nil {
    return err
}

for i, ast := range asts {
    fmt.Printf("Query %d: %d statements\n", i, len(ast.Statements))
}
ValidateMultiple

Validate multiple SQL statements:

func ValidateMultiple(queries []string) error

Example:

queries := []string{
    "SELECT * FROM users",
    "INSERT INTO logs (msg) VALUES ('test')",
}

if err := gosqlx.ValidateMultiple(queries); err != nil {
    return fmt.Errorf("validation failed: %w", err)
}
Formatting Functions
Format

Format SQL according to specified options:

func Format(sql string, options FormatOptions) (string, error)

Example:

opts := gosqlx.DefaultFormatOptions()
opts.AddSemicolon = true
opts.UppercaseKeywords = true

formatted, err := gosqlx.Format("select * from users", opts)
// Returns validated SQL with semicolon added
FormatOptions

Control formatting behavior:

type FormatOptions struct {
    IndentSize        int  // Number of spaces for indentation (default: 2)
    UppercaseKeywords bool // Uppercase SQL keywords (default: false)
    AddSemicolon      bool // Add semicolon if missing (default: false)
    SingleLineLimit   int  // Max line length before breaking (default: 80)
}

Note: Full AST-based formatting is planned for a future release. Current implementation validates SQL and applies basic formatting options.

Use Cases

1. Input Validation
func validateUserQuery(userSQL string) error {
    // Quick validation before executing
    if err := gosqlx.Validate(userSQL); err != nil {
        return fmt.Errorf("invalid SQL: %w", err)
    }
    return nil
}
2. SQL Analysis Tool
func analyzeSQL(sql string) error {
    ast, err := gosqlx.Parse(sql)
    if err != nil {
        return err
    }

    // Analyze the AST
    for _, stmt := range ast.Statements {
        switch s := stmt.(type) {
        case *ast.SelectStatement:
            fmt.Println("Found SELECT statement")
        case *ast.InsertStatement:
            fmt.Println("Found INSERT statement")
        // Handle other statement types
        }
    }

    return nil
}
3. Batch Query Processing
func processMigrationFiles(files []string) error {
    var queries []string

    // Read all SQL files
    for _, file := range files {
        content, err := os.ReadFile(file)
        if err != nil {
            return err
        }
        queries = append(queries, string(content))
    }

    // Validate all at once
    if err := gosqlx.ValidateMultiple(queries); err != nil {
        return fmt.Errorf("migration validation failed: %w", err)
    }

    // Parse all efficiently
    asts, err := gosqlx.ParseMultiple(queries)
    if err != nil {
        return err
    }

    // Process each migration
    for i, ast := range asts {
        fmt.Printf("Migration %s: %d statements\n", files[i], len(ast.Statements))
    }

    return nil
}
4. SQL Formatting Service
func formatSQLEndpoint(w http.ResponseWriter, r *http.Request) {
    sql := r.FormValue("sql")

    opts := gosqlx.DefaultFormatOptions()
    opts.AddSemicolon = true
    opts.IndentSize = 4

    formatted, err := gosqlx.Format(sql, opts)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    w.Write([]byte(formatted))
}

Migration from Low-Level API

If you're currently using the low-level tokenizer and parser APIs directly, migrating to gosqlx is simple:

Before (Low-Level API)
import (
    "github.com/ajitpratap0/GoSQLX/pkg/sql/tokenizer"
    "github.com/ajitpratap0/GoSQLX/pkg/sql/parser"
)

func parseSQL(sql string) (*ast.AST, error) {
    // Get tokenizer from pool
    tkz := tokenizer.GetTokenizer()
    defer tokenizer.PutTokenizer(tkz)

    // Tokenize
    tokens, err := tkz.Tokenize([]byte(sql))
    if err != nil {
        return nil, err
    }

    // Convert tokens
    converter := parser.NewTokenConverter()
    result, err := converter.Convert(tokens)
    if err != nil {
        return nil, err
    }

    // Parse
    p := parser.NewParser()
    defer p.Release()

    return p.Parse(result.Tokens)
}
After (High-Level API)
import "github.com/ajitpratap0/GoSQLX/pkg/gosqlx"

func parseSQL(sql string) (*ast.AST, error) {
    return gosqlx.Parse(sql)
}

Benefits:

  • Less boilerplate code
  • Automatic resource management
  • Simpler error handling
  • Same performance characteristics

Best Practices

1. Use Validate for Quick Checks

If you only need to check syntax validity, use Validate instead of Parse:

// Good - faster for validation only
if err := gosqlx.Validate(sql); err != nil {
    return err
}

// Less efficient - builds full AST
if _, err := gosqlx.Parse(sql); err != nil {
    return err
}
2. Batch Processing

For multiple queries, use batch functions to reuse parser resources:

// Good - reuses resources
asts, err := gosqlx.ParseMultiple(queries)

// Less efficient - recreates resources for each query
for _, sql := range queries {
    ast, err := gosqlx.Parse(sql)
    // ...
}
3. Use MustParse Only for Literals

Use MustParse only with SQL you control (tests, constants):

// Good - SQL literal in code
var testQuery = gosqlx.MustParse("SELECT 1")

// Bad - user input could panic
ast := gosqlx.MustParse(userInput) // Don't do this!
4. Performance-Critical Code

For performance-critical applications, consider using the low-level API directly:

// High-level API - simpler but slight overhead
ast, err := gosqlx.Parse(sql)

// Low-level API - more control, slightly faster
tkz := tokenizer.GetTokenizer()
defer tokenizer.PutTokenizer(tkz)
// ... manual token/parse operations

Error Handling

All functions return descriptive errors with context:

ast, err := gosqlx.Parse("SELECT * FROM")
if err != nil {
    // Error includes position and context
    fmt.Printf("Parse error: %v\n", err)
    // Output: Parse error: parsing failed: unexpected EOF at line 1, column 14
}

Batch functions include query index in error messages:

err := gosqlx.ValidateMultiple(queries)
if err != nil {
    // Error includes query number
    fmt.Printf("Error: %v\n", err)
    // Output: Error: query 2: invalid SQL: unexpected token 'FROM'
}

Supported SQL Features

The gosqlx package supports all SQL features provided by GoSQLX:

  • DML: SELECT, INSERT, UPDATE, DELETE
  • DDL: CREATE, ALTER, DROP
  • JOINs: INNER, LEFT, RIGHT, FULL OUTER, CROSS, NATURAL
  • Subqueries: Scalar, row, table subqueries
  • Window Functions: All SQL-99 window functions with OVER clause
  • CTEs: WITH clause, recursive CTEs
  • Set Operations: UNION, INTERSECT, EXCEPT
  • Advanced Clauses: GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET
  • Multiple Dialects: PostgreSQL, MySQL, SQL Server, Oracle, SQLite

Performance

The high-level API has minimal overhead compared to the low-level API:

BenchmarkParse-8              50000    ~30-50 μs/op    ~15 KB/op
BenchmarkParseMultiple-8      10000   ~150-200 μs/op   ~75 KB/op (5 queries)
BenchmarkValidate-8           50000    ~30-50 μs/op    ~15 KB/op
BenchmarkFormat-8             45000    ~35-55 μs/op    ~16 KB/op

Object pooling keeps allocations low and performance high.

Examples

See comprehensive examples in:

Advanced Usage

For advanced use cases requiring fine-grained control:

  • Use the low-level APIs in pkg/sql/tokenizer and pkg/sql/parser
  • Access AST visitor pattern in pkg/sql/ast/visitor.go
  • Implement custom AST traversal and analysis

Contributing

Contributions are welcome! Please see the main GoSQLX repository for contribution guidelines.

License

This package is part of GoSQLX. See the main repository for license information.

Documentation

Overview

Package gosqlx provides convenient high-level functions for SQL parsing.

This package wraps the lower-level tokenizer and parser APIs to provide a simple, ergonomic interface for common operations. All object pool management is handled internally.

For performance-critical applications that need fine-grained control, use the lower-level APIs in pkg/sql/tokenizer and pkg/sql/parser directly.

Example (AdvancedFeatures)

Example_advancedFeatures demonstrates parsing advanced SQL features.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	// Window functions
	windowSQL := "SELECT name, ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) as rank FROM employees"
	ast1, err := gosqlx.Parse(windowSQL)
	if err != nil {
		log.Fatal(err)
	}

	// CTEs
	cteSQL := "WITH active AS (SELECT * FROM users WHERE active = true) SELECT * FROM active"
	ast2, err := gosqlx.Parse(cteSQL)
	if err != nil {
		log.Fatal(err)
	}

	// JOINs
	joinSQL := "SELECT u.name, o.total FROM users u INNER JOIN orders o ON u.id = o.user_id"
	ast3, err := gosqlx.Parse(joinSQL)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Parsed window: %d, CTE: %d, JOIN: %d\n", len(ast1.Statements), len(ast2.Statements), len(ast3.Statements))
}
Output:

Parsed window: 1, CTE: 1, JOIN: 1
Example (Batch)

Example_batch demonstrates parsing multiple SQL statements efficiently.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	queries := []string{
		"SELECT * FROM users",
		"SELECT * FROM orders",
		"SELECT * FROM products",
	}

	asts, err := gosqlx.ParseMultiple(queries)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Successfully parsed %d queries\n", len(asts))
}
Output:

Successfully parsed 3 queries
Example (BatchValidation)

Example_batchValidation demonstrates validating multiple queries.

package main

import (
	"fmt"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	queries := []string{
		"SELECT * FROM users",
		"INSERT INTO logs (message) VALUES ('test')",
		"UPDATE users SET active = false WHERE id = 1",
		"DELETE FROM temp_data WHERE created_at < NOW()",
	}

	if err := gosqlx.ValidateMultiple(queries); err != nil {
		fmt.Printf("Validation failed: %v\n", err)
		return
	}

	fmt.Printf("All %d queries are valid\n", len(queries))
}
Output:

All 4 queries are valid
Example (ComplexQuery)

Example_complexQuery demonstrates parsing a complex SQL query.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	sql := `
		SELECT
			u.id,
			u.name,
			COUNT(o.id) as order_count
		FROM users u
		LEFT JOIN orders o ON u.id = o.user_id
		WHERE u.active = true
		GROUP BY u.id, u.name
		ORDER BY order_count DESC
	`

	ast, err := gosqlx.Parse(sql)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Parsed complex query with %d statement(s)\n", len(ast.Statements))
}
Output:

Parsed complex query with 1 statement(s)
Example (Cte)

Example_cte demonstrates parsing Common Table Expressions (CTEs).

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	sql := `
		WITH active_users AS (
			SELECT * FROM users WHERE active = true
		)
		SELECT * FROM active_users
	`

	ast, err := gosqlx.Parse(sql)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Successfully parsed CTE query\n")
	_ = ast
}
Output:

Successfully parsed CTE query
Example (ErrorHandling)

Example_errorHandling demonstrates proper error handling.

package main

import (
	"fmt"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	sql := "SELECT * FROM" // Invalid: missing table name

	ast, err := gosqlx.Parse(sql)
	if err != nil {
		fmt.Println("Parse error occurred")
		// In real code: log detailed error message
		_ = err
		return
	}

	_ = ast
}
Output:

Parse error occurred
Example (Format)

Example_format demonstrates SQL formatting with options.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	sql := "SELECT * FROM users WHERE active = true"

	// Use default formatting options
	opts := gosqlx.DefaultFormatOptions()
	opts.AddSemicolon = true

	formatted, err := gosqlx.Format(sql, opts)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Formatted SQL length: %d\n", len(formatted))
}
Output:

Formatted SQL length: 40
Example (FormatWithOptions)

Example_formatWithOptions demonstrates custom formatting options.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	sql := "SELECT id, name FROM users"

	opts := gosqlx.FormatOptions{
		IndentSize:        4,
		UppercaseKeywords: true,
		AddSemicolon:      true,
		SingleLineLimit:   80,
	}

	formatted, err := gosqlx.Format(sql, opts)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Formatted with custom options: %d chars\n", len(formatted))
}
Output:

Formatted with custom options: 27 chars
Example (MigrationFromLowLevel)

Example_migrationFromLowLevel demonstrates migrating from low-level API.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	// Instead of manually managing tokenizer and parser:
	// tkz := tokenizer.GetTokenizer()
	// defer tokenizer.PutTokenizer(tkz)
	// tokens, err := tkz.Tokenize([]byte(sql))
	// ...
	// p := parser.NewParser()
	// defer p.Release()
	// ast, err := p.Parse(tokens)

	// Simply use:
	ast, err := gosqlx.Parse("SELECT * FROM users")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Migrated to simple API: %d statement(s)\n", len(ast.Statements))
}
Output:

Migrated to simple API: 1 statement(s)
Example (MustParse)

Example_mustParse demonstrates MustParse for SQL literals.

package main

import (
	"fmt"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	// Use MustParse only with SQL literals you control
	// (e.g., in tests or initialization code)
	ast := gosqlx.MustParse("SELECT 1")

	fmt.Printf("Type: %T\n", ast)
}
Output:

Type: *ast.AST
Example (ParseBytes)

Example_parseBytes demonstrates parsing from a byte slice.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	// Useful when SQL is already in byte form (e.g., from file I/O)
	sqlBytes := []byte("SELECT * FROM users")

	ast, err := gosqlx.ParseBytes(sqlBytes)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Parsed from bytes: %d statement(s)\n", len(ast.Statements))
}
Output:

Parsed from bytes: 1 statement(s)
Example (RealWorldUsage)

Example_realWorldUsage demonstrates a realistic use case.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	// Validate user input before executing
	userSQL := "SELECT * FROM users WHERE id = 1"

	// First validate
	if err := gosqlx.Validate(userSQL); err != nil {
		fmt.Println("Invalid SQL from user")
		return
	}

	// Parse to inspect structure
	ast, err := gosqlx.Parse(userSQL)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Valid query with %d statement(s)\n", len(ast.Statements))
}
Output:

Valid query with 1 statement(s)
Example (Simple)

Example_simple demonstrates the simplest way to parse SQL.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	sql := "SELECT * FROM users"

	ast, err := gosqlx.Parse(sql)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Parsed %d statement(s)\n", len(ast.Statements))
}
Output:

Parsed 1 statement(s)
Example (Validate)

Example_validate demonstrates SQL validation.

package main

import (
	"fmt"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	// Valid SQL
	if err := gosqlx.Validate("SELECT * FROM users"); err != nil {
		fmt.Println("Invalid SQL")
	} else {
		fmt.Println("Valid SQL")
	}

	// Invalid SQL
	if err := gosqlx.Validate("INVALID SQL"); err != nil {
		fmt.Println("Invalid SQL detected")
	}

}
Output:

Valid SQL
Invalid SQL detected
Example (ValidateMultiple)

Example_validateMultiple demonstrates validating multiple SQL statements.

package main

import (
	"fmt"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	queries := []string{
		"SELECT * FROM users",
		"INSERT INTO users (name) VALUES ('test')",
		"UPDATE users SET active = true WHERE id = 1",
	}

	if err := gosqlx.ValidateMultiple(queries); err != nil {
		fmt.Printf("Validation failed: %v\n", err)
		return
	}

	fmt.Println("All queries are valid")
}
Output:

All queries are valid
Example (WindowFunctions)

Example_windowFunctions demonstrates parsing SQL with window functions.

package main

import (
	"fmt"
	"log"

	"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
)

func main() {
	sql := "SELECT name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) as rank FROM employees"

	ast, err := gosqlx.Parse(sql)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Successfully parsed window function query\n")
	_ = ast
}
Output:

Successfully parsed window function query

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Format

func Format(sql string, options FormatOptions) (string, error)

Format formats SQL according to the specified options.

This is a placeholder implementation that currently validates the SQL and returns it with basic formatting. Full AST-based formatting will be implemented in a future version.

Example:

sql := "select * from users where active=true"
opts := gosqlx.DefaultFormatOptions()
opts.UppercaseKeywords = true
formatted, err := gosqlx.Format(sql, opts)

Returns the formatted SQL string or an error if SQL is invalid.

Example

Example demonstrating SQL formatting

sql := "SELECT * FROM users WHERE active = true"
opts := DefaultFormatOptions()
opts.AddSemicolon = true

formatted, err := Format(sql, opts)
if err != nil {
	panic(err)
}

_ = formatted

func MustParse

func MustParse(sql string) *ast.AST

MustParse is like Parse but panics on error.

This is useful for parsing SQL literals at startup or in tests where parse errors indicate a programming bug.

Example:

// In test or init()
ast := gosqlx.MustParse("SELECT 1")

func Parse

func Parse(sql string) (*ast.AST, error)

Parse is a convenience function that tokenizes and parses SQL in one call.

This function handles all object pool management internally, making it ideal for simple use cases where performance overhead is acceptable.

Example:

sql := "SELECT * FROM users WHERE active = true"
astNode, err := gosqlx.Parse(sql)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Parsed: %T\n", astNode)

For batch processing or performance-critical code, use the lower-level tokenizer and parser APIs directly to reuse objects.

Example

Example demonstrating the simple Parse API

sql := "SELECT * FROM users WHERE active = true"

ast, err := Parse(sql)
if err != nil {
	panic(err)
}

// Use the AST
_ = ast

func ParseBytes

func ParseBytes(sql []byte) (*ast.AST, error)

ParseBytes is like Parse but accepts a byte slice.

This is useful when you already have SQL as bytes (e.g., from file I/O) and want to avoid the string → []byte conversion overhead.

Example:

sqlBytes := []byte("SELECT * FROM users")
astNode, err := gosqlx.ParseBytes(sqlBytes)

func ParseMultiple

func ParseMultiple(queries []string) ([]*ast.AST, error)

ParseMultiple parses multiple SQL statements and returns their ASTs.

This is more efficient than calling Parse() repeatedly because it reuses the tokenizer and parser objects.

Example:

queries := []string{
    "SELECT * FROM users",
    "SELECT * FROM orders",
}
asts, err := gosqlx.ParseMultiple(queries)
Example

Example demonstrating batch parsing

queries := []string{
	"SELECT * FROM users",
	"SELECT * FROM orders",
}

asts, err := ParseMultiple(queries)
if err != nil {
	panic(err)
}

for i, ast := range asts {
	_ = i
	_ = ast
}

func ParseWithContext

func ParseWithContext(ctx context.Context, sql string) (*ast.AST, error)

ParseWithContext is a convenience function that tokenizes and parses SQL with context support.

This function handles all object pool management internally and supports cancellation via the provided context. It's ideal for long-running operations that need to be cancellable or have timeouts.

Returns context.Canceled if the context is cancelled during parsing, or context.DeadlineExceeded if the timeout expires.

Example:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
astNode, err := gosqlx.ParseWithContext(ctx, sql)
if err == context.DeadlineExceeded {
    log.Println("Parsing timed out")
}

func ParseWithTimeout

func ParseWithTimeout(sql string, timeout time.Duration) (*ast.AST, error)

ParseWithTimeout is a convenience function that parses SQL with a timeout.

This is a wrapper around ParseWithContext that creates a timeout context automatically. It's useful for quick timeout-based parsing without manual context management.

Example:

astNode, err := gosqlx.ParseWithTimeout(sql, 5*time.Second)
if err == context.DeadlineExceeded {
    log.Println("Parsing timed out after 5 seconds")
}

func Validate

func Validate(sql string) error

Validate checks if the given SQL is syntactically valid.

This is a convenience function that only validates syntax without building the full AST, making it slightly faster than Parse().

Example:

if err := gosqlx.Validate("SELECT * FROM users"); err != nil {
    fmt.Printf("Invalid SQL: %v\n", err)
}

Returns nil if SQL is valid, or an error describing the problem.

Example

Example demonstrating SQL validation

if err := Validate("SELECT * FROM users"); err != nil {
	panic(err)
}

func ValidateMultiple

func ValidateMultiple(queries []string) error

ValidateMultiple validates multiple SQL statements.

Returns nil if all statements are valid, or an error for the first invalid statement encountered.

Example:

queries := []string{
    "SELECT * FROM users",
    "INVALID SQL HERE",
}
if err := gosqlx.ValidateMultiple(queries); err != nil {
    fmt.Printf("Validation failed: %v\n", err)
}

Types

type FormatOptions

type FormatOptions struct {
	// IndentSize is the number of spaces to use for indentation (default: 2)
	IndentSize int

	// Uppercase keywords (default: false)
	UppercaseKeywords bool

	// AddSemicolon adds a semicolon at the end if missing (default: false)
	AddSemicolon bool

	// SingleLineLimit is the maximum line length before breaking (default: 80)
	// Note: Currently a placeholder for future implementation
	SingleLineLimit int
}

FormatOptions controls SQL formatting behavior.

func DefaultFormatOptions

func DefaultFormatOptions() FormatOptions

DefaultFormatOptions returns the default formatting options.

Jump to

Keyboard shortcuts

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