### Docker Image Setup for Unqueryvet Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Dockerfile example to create a Docker image that includes Unqueryvet, a configuration file, and sets it up to run checks. ```dockerfile FROM golang:1.24-alpine # Install unqueryvet RUN go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest # Copy config COPY .unqueryvet.yaml /workspace/.unqueryvet.yaml # Run checks WORKDIR /workspace CMD ["unqueryvet", "-quiet", "./..."] ``` -------------------------------- ### Install unqueryvet-lsp Source: https://github.com/mirrexone/unqueryvet/blob/main/extensions/vscode/README.md Manually install the unqueryvet Language Server Protocol (LSP) binary using Go. This is an optional step if automatic installation fails or is not preferred. ```bash go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet-lsp@latest ``` -------------------------------- ### Development Setup and Build Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md This sequence clones the repository, downloads dependencies, runs tests, and builds the project binaries. It's a comprehensive setup for contributing. ```bash git clone https://github.com/MirrexOne/unqueryvet.git cd unqueryvet go mod download go test ./... go build ./... ``` -------------------------------- ### Install CLI and LSP Server with Go Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Install the CLI and LSP server locally using Go commands. This makes the executables available in your PATH. ```bash go install ./cmd/unqueryvet go install ./cmd/unqueryvet-lsp ``` -------------------------------- ### Install Unqueryvet Go Binary Source: https://github.com/mirrexone/unqueryvet/blob/main/RELEASE.md Installs the latest stable version of the Unqueryvet Go binary using `go install`. This command fetches and builds the specified package. ```bash # Test Go installation go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest ``` -------------------------------- ### Start LSP Server Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Command to start the Unqueryvet LSP server for IDE integration. ```bash unqueryvet-lsp ``` -------------------------------- ### Install Unqueryvet LSP Go Binary Source: https://github.com/mirrexone/unqueryvet/blob/main/RELEASE.md Installs the latest stable version of the Unqueryvet Language Server Protocol (LSP) binary using `go install`. This is used for IDE integration. ```bash # Test LSP installation go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet-lsp@latest ``` -------------------------------- ### Install Unqueryvet Standalone Tool Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Installs the Unqueryvet command-line interface using go install. This is the primary method for using Unqueryvet as a standalone tool. ```bash go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest ``` -------------------------------- ### Install CLI and LSP Server with Task Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Install the CLI and LSP server locally using the Task build tool. This makes the executables available in your PATH. ```bash task install:all ``` -------------------------------- ### Build and Install VS Code Extension Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Steps to build and install the Unqueryvet VS Code extension from its source directory. ```bash cd extensions/vscode npm install npm run compile npm run package # Install the generated .vsix file ``` -------------------------------- ### SELECT * Detection Example Source: https://github.com/mirrexone/unqueryvet/blob/main/extensions/vscode/README.md Illustrates the detection of `SELECT *` usage in raw SQL queries. The first example is flagged as an issue, while the second, which specifies columns, is considered good practice. ```go // Detected as issue query := "SELECT * FROM users" // Good - explicit columns query := "SELECT id, name, email FROM users" ``` -------------------------------- ### Configuration File Example Source: https://github.com/mirrexone/unqueryvet/blob/main/extensions/vscode/README.md Configure unqueryvet rules, ignored files, and allowed patterns using a `.unqueryvet.yaml` file in your project root. This allows for fine-grained control over analysis. ```yaml rules: select-star: warning n1-queries: warning sql-injection: error ignore: - "*_test.go" - "vendor/**" allow: - "COUNT(*)" ``` -------------------------------- ### Dockerfile for Unqueryvet Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md This Dockerfile sets up a build environment for Unqueryvet and then creates a lean runtime image. It installs the tool and sets it as the entrypoint. ```dockerfile FROM golang:1.24-alpine AS builder RUN go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest FROM alpine:latest COPY --from=builder /go/bin/unqueryvet /usr/local/bin/ ENTRYPOINT ["unqueryvet"] ``` -------------------------------- ### Unqueryvet Configuration File Example Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Create and use a .unqueryvet.yaml file to set global severity, enable checks for SQL builders, configure specific rule severities, and define ignored files. ```bash # Create config file cat > .unqueryvet.yaml << 'EOF' severity: warning check-sql-builders: true # Rules are enabled by default - configure severity if needed rules: select-star: warning n1-queries: warning sql-injection: error ignore: - "*_test.go" - "vendor/**" EOF # Run (auto-loads config) unqueryvet ./... ``` -------------------------------- ### Verify unqueryvet LSP Server Installation Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Checks if the unqueryvet LSP server has been installed correctly by displaying its version. ```bash unqueryvet-lsp -version ``` -------------------------------- ### N+1 Query Detection Example Source: https://github.com/mirrexone/unqueryvet/blob/main/extensions/vscode/README.md Demonstrates the identification of N+1 query problems where a database query is executed inside a loop. The example shows a detected issue and a recommended alternative using JOIN or batch queries. ```go // Detected as issue - query inside loop for _, user := range users { orders, _ := db.Query("SELECT * FROM orders WHERE user_id = ?", user.ID) } // Good - use JOIN or batch query query := "SELECT u.*, o.* FROM users u JOIN orders o ON u.id = o.user_id" ``` -------------------------------- ### Download Go Dependencies Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Download all project dependencies using Go modules. Ensure you have Go 1.24 or later installed. ```bash go mod download ``` -------------------------------- ### Full Unqueryvet Configuration Example Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md A comprehensive configuration including severity, detailed rules for SQL analysis, core analysis options, and file patterns to ignore or allow. ```yaml # Diagnostic severity: "error" or "warning" severity: warning # Rules configuration (all enabled by default) # N+1 and SQL injection are controlled via rules, not separate flags rules: select-star: warning n1-queries: warning sql-injection: error # Core analysis options check-sql-builders: true check-aliased-wildcard: true check-string-concat: true check-format-strings: true check-string-builder: true check-subqueries: true # File patterns to ignore (glob) ignore: - "*_test.go" - "testdata/**" - "vendor/**" # Allowed SELECT * patterns allow: - "COUNT(*)" - "information_schema.*" ``` -------------------------------- ### Correct Transaction Handling (Good) Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md This example shows the correct way to handle database transactions by ensuring a rollback is deferred and then explicitly committing the transaction. It also includes an example using the callback pattern, which automatically manages transaction commit/rollback. ```go func createUser(db *sql.DB, name string) error { tx, err := db.Begin() if err != nil { return err } defer tx.Rollback() // Safe: called after Commit() is a no-op _, err = tx.Exec("INSERT INTO users (name) VALUES (?)", name) if err != nil { return err // Rollback will be called via defer } return tx.Commit() } // Using callback pattern (automatically handled) func createUserCallback(db *pgx.Conn, name string) error { return db.BeginFunc(ctx, func(tx pgx.Tx) error { _, err := tx.Exec(ctx, "INSERT INTO users (name) VALUES ($1)", name) return err // Commit/Rollback handled automatically }) } ``` -------------------------------- ### Build VS Code Extension Source: https://github.com/mirrexone/unqueryvet/blob/main/RELEASE.md Install dependencies, compile, and package the VS Code extension locally. ```bash cd extensions/vscode npm install npm run compile npx @vscode/vsce package ``` -------------------------------- ### Enable Verbose Mode Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Use verbose mode to get detailed output, including debug messages, diagnostics, examples, and performance impact. ```bash $ unqueryvet -verbose ./myapp.go ``` -------------------------------- ### SQL Injection Detection Example Source: https://github.com/mirrexone/unqueryvet/blob/main/extensions/vscode/README.md Highlights SQL injection vulnerabilities caused by string formatting or concatenation. The example shows a detected issue using `fmt.Sprintf` and a secure alternative using parameterized queries. ```go // Detected as issue query := fmt.Sprintf("SELECT * FROM users WHERE name = '%s'", userName) // Good - parameterized query query := "SELECT * FROM users WHERE name = ?" db.Query(query, userName) ``` -------------------------------- ### Interactive Fix Mode Example Session Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md An example of an interactive session where Unqueryvet presents issues and prompts for user action, such as applying a fix or skipping. ```text Found 15 issues. Review each one: [1/15] internal/api/users.go:42:15 ───────────────────────────────────── 41 | func getUsers(db *sql.DB) { 42 | query := "SELECT * FROM users" | ^^^^^^^^^^^^^^^^^^^^^ avoid SELECT * 43 | rows, _ := db.Query(query) Suggestions: 1. SELECT id, username, email, created_at (from struct User) 2. SELECT id, username, email 3. Skip this issue 4. Edit manually Your choice [1-4]: _ ``` -------------------------------- ### Create custom unqueryvet configuration Source: https://github.com/mirrexone/unqueryvet/blob/main/_examples/README.md Example of a custom unqueryvet configuration file. This demonstrates setting severity, enabling/disabling rules, configuring SQL builders, and specifying ignored files and allowed SELECT * patterns. ```yaml # .unqueryvet.yaml in your project root severity: warning # Rules configuration (all enabled by default) # N+1 and SQL injection are controlled via rules section rules: select-star: warning n1-queries: warning sql-injection: error # Core checks check-sql-builders: true check-aliased-wildcard: true check-string-concat: true check-format-strings: true check-subqueries: true # SQL builders (enable only what you use) sql-builders: gorm: true sqlx: true # ... others disabled # Project-specific patterns ignore: - "*_test.go" - "testdata/**" - "vendor/**" - "migrations/**" # Allow SELECT * for specific tables allow: - "SELECT \* FROM audit_log" - "SELECT \* FROM temp_.*" ``` -------------------------------- ### Function Call String Match Condition Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md Uses the matches() function to check if the 'function' variable starts with 'Get', 'List', or 'Find'. ```yaml when: matches(function, "^(Get|List|Find)") ``` -------------------------------- ### Environment-Aware Rules for SELECT * Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md This example demonstrates environment-aware rules, differentiating between production and test code. It flags SELECT * as an error in production while issuing a milder info message in test environments. ```yaml custom-rules: # Strict in production code - id: strict-prod-select-star pattern: SELECT * FROM $TABLE when: | !matches(file, "_test\.go$") && !matches(file, "testdata/") && !matches(file, "internal/debug/") && !isSystemTable(table) && !isTempTable(table) severity: error message: "SELECT * is not allowed in production code" # Warning in test code - id: test-select-star pattern: SELECT * FROM $TABLE when: matches(file, "_test\.go$") severity: info message: "Consider using explicit columns even in tests" ``` -------------------------------- ### GitHub Actions CI for SQL Linting Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md This GitHub Actions workflow automates SQL linting on push and pull requests. It checks out code, sets up Go, installs unqueryvet, and runs the linter. ```yaml name: SQL Lint on: [push, pull_request] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v6 with: go-version: '1.24' - name: Install unqueryvet run: go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest - name: Run unqueryvet run: unqueryvet -n1 -sqli -tx-leak ./... ``` -------------------------------- ### Start Interactive TUI Mode Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Command to launch Unqueryvet in interactive TUI mode to fix issues. ```bash unqueryvet -fix ./... ``` -------------------------------- ### Detecting SELECT * Queries Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Examples of code that directly or indirectly uses SELECT * which can be inefficient or problematic. This includes aliased wildcards, subqueries, string concatenation, format strings, and SQL builder patterns. ```go // Direct SELECT * query := "SELECT * FROM users" // Aliased wildcard query := "SELECT t.* FROM users t" // In subquery query := "SELECT id FROM (SELECT * FROM users)" // String concatenation query := "SELECT * " + "FROM users" // Format string query := fmt.Sprintf("SELECT * FROM %s", table) // SQL builders squirrel.Select("*").From("users") db.Model(&User{}).Select("*") goqu.From("users").Select(goqu.Star()) ``` ```go // Explicit columns query := "SELECT id, name, email FROM users" // SQL builders squirrel.Select("id", "name", "email").From("users") db.Model(&User{}).Select("id", "name", "email") goqu.From("users").Select("id", "name", "email") ``` -------------------------------- ### Sync and Rebase with Upstream Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Before starting new work, sync your local repository with the upstream main branch using 'git fetch' and 'git rebase'. ```bash git fetch upstream git rebase upstream/main ``` -------------------------------- ### CI/CD Integration with GitHub Actions Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Example of setting up Unqueryvet in a GitHub Actions workflow to lint code on push or pull request events. ```yaml # GitHub Actions name: SQL Lint on: [push, pull_request] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 - name: Install unqueryvet run: go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest - name: Run unqueryvet run: unqueryvet -quiet -n1 -sqli ./... ``` -------------------------------- ### Unqueryvet Custom Rules: Pattern Matching Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Define custom rules using patterns, conditions, and actions. This example shows how to allow temporary tables, flag dangerous deletes, and enforce transaction timeouts. ```yaml custom-rules: - id: allow-temp-tables pattern: SELECT * FROM $TABLE when: isTempTable(table) action: allow - id: dangerous-delete pattern: DELETE FROM $TABLE when: "!has_where" message: "DELETE without WHERE clause" severity: error - id: require-tx-timeout pattern: db.BeginTx($CTX, $OPTS) when: "!contains(opts, 'Timeout')" message: "Transaction should have timeout set" severity: warning ``` -------------------------------- ### Ignore Large Generated Files Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Example configuration for the .unqueryvet.yaml file to ignore specific generated files, helping to manage memory usage. ```yaml # .unqueryvet.yaml ignored-files: - "**/*_generated.go" - "**/wire_gen.go" ``` -------------------------------- ### Negated Pattern Example Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md Matches when the specified pattern does NOT occur. Use this to find code lacking certain clauses, like WHERE. ```yaml pattern: "!WHERE" ``` -------------------------------- ### Example Commit Message Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Follow conventional commit message format. Include a type (e.g., 'feat', 'fix'), a scope, and a description. Use bullet points for detailing changes. ```git commit feat: add support for new SQL builder XYZ - Add XYZ builder detection in internal/analyzer/sqlbuilders/ - Add tests for common XYZ patterns - Update documentation ``` -------------------------------- ### Check if String Starts With Prefix Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md Use the `hasPrefix` function to determine if a string variable begins with a specified prefix. This is commonly used for identifying temporary tables or specific file naming conventions. ```go hasPrefix(table, "temp_") ``` -------------------------------- ### Display unqueryvet version information Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md This command displays detailed version information for unqueryvet, including the commit hash, build date, Go version, and platform. It is useful for verifying the installed version and for debugging purposes in CI/CD pipelines. ```bash unqueryvet -version ``` -------------------------------- ### Detect Unclosed Transactions (Bad) Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md This code snippet demonstrates a common mistake where a database transaction is started but neither committed nor rolled back, leading to a transaction leak. It also shows the 'defer in loop' anti-pattern where defers accumulate. ```go func createUser(db *sql.DB, name string) error { tx, err := db.Begin() if err != nil { return err } // Missing defer tx.Rollback() and missing tx.Commit()! _, err = tx.Exec("INSERT INTO users (name) VALUES (?)", name) if err != nil { return err // Transaction leaked! } return nil } func deferInLoop(db *sql.DB, items []string) error { for _, item := range items { tx, _ := db.Begin() defer tx.Rollback() // Defers pile up until function returns! tx.Exec("INSERT...", item) tx.Commit() } return nil } ``` -------------------------------- ### Unqueryvet Custom Rules: Advanced Conditions Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Implement advanced custom rules with complex conditions using logical operators and functions. This example detects N+1 queries within loops, excluding test files and batch operations. ```yaml custom-rules: - id: n1-detection pattern: $DB.Query($QUERY) when: | in_loop && !contains(function, "batch") && !matches(file, "_test.go$") message: "N+1 query in loop" severity: warning fix: "Use batch query or preloading" ``` -------------------------------- ### Copy configuration and run golangci-lint Source: https://github.com/mirrexone/unqueryvet/blob/main/_examples/README.md Copy the strict configuration file to the project root and then run golangci-lint. ```bash # Copy configuration to project root cp _examples/strict-config.yml .golangci.yml # Run golangci-lint golangci-lint run ./... ``` -------------------------------- ### Build CLI and LSP Server with Go Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Build the CLI and LSP server directly using Go commands. This is an alternative to using Task. ```bash go build ./cmd/unqueryvet go build ./cmd/unqueryvet-lsp ``` -------------------------------- ### Run golangci-lint with standard config Source: https://github.com/mirrexone/unqueryvet/blob/main/_examples/README.md Copy the standard golangci-lint configuration to your project and run golangci-lint. ```bash # Copy to your project cp golangci.yml ~/.golangci.yml golangci-lint run ./... ``` -------------------------------- ### Manual Publishing Steps Source: https://github.com/mirrexone/unqueryvet/blob/main/extensions/vscode/PUBLISHING.md Commands to manually publish the extension using vsce. Ensure you are logged in or provide the PAT directly. ```bash cd extensions/vscode npm install npm run compile # Login with your PAT npx @vscode/vsce login unqueryvet # Publish npx @vscode/vsce publish ``` -------------------------------- ### Build CLI and LSP Server with Task Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Build the command-line interface (CLI) and the Language Server Protocol (LSP) server using the Task build tool. Task is optional but recommended. ```bash task build task build:lsp task build:all ``` -------------------------------- ### Run Benchmarks with Task or Go Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Benchmarks can be run using the 'bench' task or directly with 'go test -bench=. -benchmem'. ```bash task bench # or go test -bench=. -benchmem ./internal/analyzer ``` -------------------------------- ### Build LSP Binaries using Script (Linux/macOS) Source: https://github.com/mirrexone/unqueryvet/blob/main/RELEASE.md Manually build LSP binaries for Linux or macOS by executing the build-lsp.sh script with a specified version. ```bash ./scripts/build-lsp.sh v1.0.0 ``` -------------------------------- ### Run golangci-lint with strict config Source: https://github.com/mirrexone/unqueryvet/blob/main/_examples/README.md Run golangci-lint using the strict configuration file. This configuration catches almost all SELECT * usage and only allows essential system queries. ```bash # Run with strict config golangci-lint run -c strict-config.yml ./... ``` -------------------------------- ### Get Length of List or String Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md Use the `len` function to retrieve the number of elements in a list or the length of a string. This is fundamental for conditional logic based on collection size. ```go len(tables) > 1 ``` -------------------------------- ### Build LSP Binaries using Task Source: https://github.com/mirrexone/unqueryvet/blob/main/RELEASE.md Execute the release build for LSP binaries using the 'build:lsp:release' task. ```bash task build:lsp:release ``` -------------------------------- ### Configure PATH for unqueryvet-lsp Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Ensure the directory containing the unqueryvet-lsp binary is included in your system's PATH environment variable. This is crucial for the IDE to find and launch the LSP server. ```bash export PATH=$PATH:$(go env GOPATH)/bin ``` -------------------------------- ### Create Builder File for New SQL Builder Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Implement the `SQLBuilderChecker` interface for your new SQL builder. This involves defining the checker, its constructor, and methods for applicability and specific checks like `SELECT *` and chained calls. ```go package sqlbuilders import ( "go/ast" ) // YourBuilderChecker checks for SELECT * in YourBuilder queries. type YourBuilderChecker struct { BaseChecker } // NewYourBuilderChecker creates a new checker for YourBuilder. func NewYourBuilderChecker() *YourBuilderChecker { return &YourBuilderChecker{ BaseChecker: BaseChecker{ name: "yourbuilder", packagePath: "github.com/example/yourbuilder", }, } } func (c *YourBuilderChecker) Name() string { return c.name } func (c *YourBuilderChecker) IsApplicable(call *ast.CallExpr) bool { // Check if this call is from yourbuilder package return c.isPackageCall(call, "yourbuilder") } func (c *YourBuilderChecker) CheckSelectStar(call *ast.CallExpr) *Violation { // Implement SELECT * detection logic return nil } func (c *YourBuilderChecker) CheckChainedCalls(call *ast.CallExpr) []*Violation { // Check method chains for SELECT * return nil } ``` -------------------------------- ### Run Unqueryvet with Docker Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Pulls the latest Unqueryvet Docker image and runs it. It mounts the current directory to /app inside the container for analysis. ```bash docker pull ghcr.io/mirrexone/unqueryvet:latest docker run --rm -v $(pwd):/app ghcr.io/mirrexone/unqueryvet /app/... ``` -------------------------------- ### Lint and Vet Code with Task Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Run 'lint' to perform static analysis with golangci-lint, and 'lint:fix' to attempt auto-fixing. 'vet' runs go vet for additional checks. ```bash task lint # Run golangci-lint task lint:fix # Run with auto-fix task vet # Run go vet ``` -------------------------------- ### Build GoLand/IntelliJ IDEA Plugin from Source Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Builds the unqueryvet plugin for GoLand and IntelliJ IDEA from its source code. Requires Gradle. ```bash cd extensions/goland ./gradlew buildPlugin ``` -------------------------------- ### Run golangci-lint with permissive config Source: https://github.com/mirrexone/unqueryvet/blob/main/_examples/README.md Run golangci-lint using the permissive configuration file. This configuration is suitable for legacy projects or gradual adoption, allowing SELECT * for system tables, temporary tables, and queries with LIMIT 1. ```bash # Run with permissive config golangci-lint run -c permissive-config.yml ./... ``` -------------------------------- ### Development Workflow CLI Commands Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Demonstrates common Unqueryvet CLI commands for development, including normal, verbose, quiet, full analysis, and interactive fix modes. ```bash # Quick check during development (normal output) $ unqueryvet ./... ``` ```bash # Detailed check before commit (verbose) $ unqueryvet -verbose ./... ``` ```bash # Fast check (quiet mode) $ unqueryvet -quiet ./... ``` ```bash # Full analysis with all checks $ unqueryvet -n1 -sqli -stats ./... ``` ```bash # Interactive fix mode $ unqueryvet -fix ./... ``` -------------------------------- ### Run Tests with Go CLI Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Execute tests directly using the 'go test' command. Options include verbose output, race detection, and generating coverage reports. ```bash go test ./... go test -v -race ./... go test -coverprofile=coverage.out ./... ``` -------------------------------- ### Build LSP Binaries using Script (Windows) Source: https://github.com/mirrexone/unqueryvet/blob/main/RELEASE.md Manually build LSP binaries for Windows by executing the build-lsp.ps1 PowerShell script with a specified version. ```powershell powershell ./scripts/build-lsp.ps1 -Version v1.0.0 ``` -------------------------------- ### Neovim Configuration with nvim-lspconfig Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Configure Unqueryvet LSP in Neovim using nvim-lspconfig. Add this to your init.lua file. ```lua local lspconfig = require('lspconfig') local configs = require('lspconfig.configs') -- Define unqueryvet LSP if not configs.unqueryvet then configs.unqueryvet = { default_config = { cmd = { 'unqueryvet-lsp' }, filetypes = { 'go' }, root_dir = lspconfig.util.root_pattern('go.mod', '.git'), settings = {}, }, } end -- Setup lspconfig.unqueryvet.setup({ on_attach = function(client, bufnr) -- Your on_attach configuration end, }) ``` -------------------------------- ### Bun: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md With Bun, use the `Column()` method to specify the columns you want to select, rather than relying on the default `SELECT *`. ```go db.NewSelect().Model(&users).Column("id", "name", "email").Scan(ctx) ``` -------------------------------- ### Publishing with PAT Directly Source: https://github.com/mirrexone/unqueryvet/blob/main/extensions/vscode/PUBLISHING.md A command to publish the extension directly using a Personal Access Token (PAT). Replace YOUR_PAT_TOKEN with your actual token. ```bash npx @vscode/vsce publish -p YOUR_PAT_TOKEN ``` -------------------------------- ### SQLBoiler: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md When using SQLBoiler, employ `qm.Select()` to explicitly list the columns you need. Avoid loading all columns by default with methods like `All()` or `FindUser()` without specifying columns. ```go users, err := models.Users( qm.Select("id", "name", "email"), ).All(ctx, db) ``` -------------------------------- ### Debug Configuration Loading Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Commands to help debug why the .unqueryvet.yaml configuration file might not be loading. This includes checking file location, verbose output, and YAML syntax. ```bash # Check config file location $ find . -name ".unqueryvet.yaml" ``` ```bash # Run with verbose to see what config is loaded $ unqueryvet -verbose ./... 2>&1 | grep -i config ``` ```bash # Validate YAML syntax $ cat .unqueryvet.yaml | yaml-lint ``` -------------------------------- ### Basic Unqueryvet Commands Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Analyze packages with default rules, enable verbose or quiet output, show statistics, enter interactive fix mode, or display the version. ```bash # Analyze all packages (all rules enabled by default) unqueryvet ./... ``` ```bash # Verbose output with explanations unqueryvet -verbose ./... ``` ```bash # Quiet mode (errors only) for CI/CD unqueryvet -quiet ./... ``` ```bash # Show statistics unqueryvet -stats ./... ``` ```bash # Interactive fix mode unqueryvet -fix ./... ``` ```bash # Show version unqueryvet -version ``` -------------------------------- ### Sublime Text Configuration (LSP package) Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Configure Unqueryvet client in Sublime Text using the LSP package. Add this to your LSP settings. ```json { "clients": { "unqueryvet": { "enabled": true, "command": ["unqueryvet-lsp"], "selector": "source.go" } } } ``` -------------------------------- ### CoC.nvim Configuration Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Configure Unqueryvet language server in CoC.nvim. Add this to your coc-settings.json file. ```json { "languageserver": { "unqueryvet": { "command": "unqueryvet-lsp", "filetypes": ["go"], "rootPatterns": ["go.mod", ".git"] } } } ``` -------------------------------- ### Run Unit Tests Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Executes all unit tests within the project. This command should be run from the project's root directory. ```bash go test ./... ``` -------------------------------- ### Vim Configuration with vim-lsp Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Configure Unqueryvet LSP in Vim using vim-lsp. Add this to your .vimrc file. ```vim if executable('unqueryvet-lsp') au User lsp_setup call lsp#register_server({ \ 'name': 'unqueryvet', \ 'cmd': {server_info->['unqueryvet-lsp']}, \ 'allowlist': ['go'], \ }) endif ``` -------------------------------- ### Simple Unqueryvet Configuration Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Define built-in rule severities, specify files to ignore using glob patterns, and list allowed patterns. ```yaml # .unqueryvet.yaml rules: select-star: error # Built-in rule severity n1-queries: warning sql-injection: error ignore: - "*_test.go" - "testdata/**" allow: - "COUNT(*)" - "information_schema.*" ``` -------------------------------- ### Create and Push Git Tag Source: https://github.com/mirrexone/unqueryvet/blob/main/RELEASE.md Use this command to create a new Git tag for a release and push it to the origin repository. ```bash git tag -a v1.0.0 -m "Release v1.0.0" git push origin v1.0.0 ``` -------------------------------- ### Register New SQL Builder in Registry Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Add the new SQL builder checker to the `Registry` by conditionally appending it based on configuration. This ensures the new builder is active when enabled. ```go func NewRegistry(cfg *config.SQLBuildersConfig) *Registry { r := &Registry{checkers: make([]SQLBuilderChecker, 0)} // ... existing builders ... if cfg.YourBuilder { r.checkers = append(r.checkers, NewYourBuilderChecker()) } return r } ``` -------------------------------- ### Run All Tests with Task Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Use the 'test' task to run all tests in the project. Other tasks allow for race detection, running only short tests, unit tests, or integration tests. ```bash task test # Run all tests task test:race # Run with race detection (requires CGO) task test:short # Run short tests only task test:unit # Run unit tests only task test:integration # Run integration tests task coverage # Generate coverage report ``` -------------------------------- ### Full Unqueryvet Configuration File Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Configure built-in rules severity, diagnostic severity, core analysis options, SQL builder libraries, and file/function patterns to ignore. Also specifies allowed SELECT * patterns. ```yaml # Built-in rules severity (all enabled by default) # Available values: error, warning, info, ignore rules: select-star: warning # SELECT * detection n1-queries: warning # N+1 query detection sql-injection: error # SQL injection scanning tx-leak: warning # Transaction leak detection # Diagnostic severity for legacy options: "error" or "warning" severity: warning # Core analysis options check-sql-builders: true check-aliased-wildcard: true check-string-concat: true check-format-strings: true check-string-builder: true check-subqueries: true # SQL builder libraries to check sql-builders: squirrel: true gorm: true sqlx: true ent: true pgx: true bun: true sqlboiler: true jet: true sqlc: true goqu: true rel: true reform: true # File patterns to ignore (glob) ignored-files: - "*_test.go" - "testdata/**" - "vendor/**" - "mock_*.go" # Function patterns to ignore (regex) ignored-functions: - "debug\\..*" - "test.*" # Allowed SELECT * patterns (regex) allowed-patterns: - "SELECT \* FROM information_schema.*" - "SELECT \* FROM pg_catalog.*" - "SELECT \* FROM temp_.*" ``` -------------------------------- ### List Distribution Folder Contents Source: https://github.com/mirrexone/unqueryvet/blob/main/RELEASE.md Check the contents of the 'dist/' folder after building LSP binaries to ensure all expected files are present. ```bash ls -lh dist/ ``` -------------------------------- ### Emacs Configuration (lsp-mode) Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Configure Unqueryvet client in Emacs using lsp-mode. Add this to your Emacs configuration. ```elisp (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection '("unqueryvet-lsp")) :major-modes '(go-mode) :server-id 'unqueryvet)) ``` -------------------------------- ### Compare Normal and Quiet Mode Output Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Illustrates the difference in output between normal and quiet modes, showing how warnings are suppressed in quiet mode. ```bash # Normal mode $ unqueryvet ./... file1.go:10: warning: avoid SELECT * file2.go:20: warning: avoid SELECT * file3.go:30: error: invalid SQL syntax # Quiet mode (only errors) $ unqueryvet -quiet ./... file3.go:30: error: invalid SQL syntax ``` -------------------------------- ### Run All Code Checks with Task Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md The 'check:all' task conveniently runs formatting checks, vet, linting, and tests in one command. ```bash task check:all # fmt:check + vet + lint + test ``` -------------------------------- ### VS Code Settings for Unqueryvet Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Configuration for the Unqueryvet VS Code extension. Ensure the server path is correctly set. ```json // .vscode/settings.json { "unqueryvet.enable": true, "unqueryvet.path": "unqueryvet-lsp", // All rules enabled by default, args optional "unqueryvet.trace.server": "verbose" } ``` -------------------------------- ### reform: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md For `reform`, use `SelectOneFrom()` or similar methods and explicitly list the columns to fetch. Avoid `FindByPrimaryKeyFrom` and `FindAllFrom` when specific columns are needed. ```go db.SelectOneFrom(UserTable, "id, name, email WHERE id = ?", id) ``` -------------------------------- ### sqlc: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md For sqlc, ensure that your SQL queries in `.sql` files explicitly list the columns to be selected, rather than using `SELECT *`. ```sql -- name: GetUsers :many SELECT id, name, email FROM users; ``` -------------------------------- ### Run unqueryvet with default behavior Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Execute unqueryvet with all three detection rules enabled by default. This command analyzes all files in the current directory and its subdirectories. ```bash unqueryvet ./... ``` -------------------------------- ### SQLx: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md When using SQLx, provide the explicit column list in the `SELECT` statement instead of using `SELECT *`. ```go db.Select(&users, "SELECT id, name, email FROM users") ``` -------------------------------- ### Clone unqueryvet Repository Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Clone the unqueryvet repository locally after forking it. Navigate into the cloned directory. ```bash git clone https://github.com/YOUR_USERNAME/unqueryvet.git cd unqueryvet ``` -------------------------------- ### Basic Unqueryvet Configuration Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Sets the diagnostic severity to warning and enables checks for SQL builders and aliased wildcards. ```yaml # .unqueryvet.yaml severity: warning check-sql-builders: true check-aliased-wildcard: true ``` -------------------------------- ### Test unqueryvet CLI Analysis Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Before troubleshooting IDE-specific issues, test the unqueryvet CLI directly on a file. This helps determine if the core analysis engine is functioning correctly. ```bash unqueryvet ./your-file.go ``` -------------------------------- ### Analyze Packages Incrementally Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md A shell script to iterate over Go packages and analyze them individually, which can help reduce high memory usage on large codebases. ```bash for pkg in $(go list ./...); do unqueryvet "$pkg" done ``` -------------------------------- ### Format and Check Code Style with Task Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Use the 'fmt' task to format code according to project standards. The 'fmt:check' task verifies formatting without making changes. ```bash task fmt # Format code task fmt:check # Check formatting ``` -------------------------------- ### Helix Configuration Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Configure Unqueryvet language server in Helix. Add this to your languages.toml file. ```toml [[language]] name = "go" language-servers = ["gopls", "unqueryvet"] [language-server.unqueryvet] command = "unqueryvet-lsp" ``` -------------------------------- ### Configure Ignored Files in .unqueryvet.yaml Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md To reduce memory and CPU usage, especially in large projects, configure the `.unqueryvet.yaml` file to ignore specific directories or file patterns. This prevents the analyzer from processing unnecessary code. ```yaml ignored-files: - "vendor/**" - "node_modules/**" - "**/*_generated.go" ``` -------------------------------- ### Basic SELECT * Pattern Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md Matches any SELECT * query. Use this to identify simple select all statements. ```yaml pattern: SELECT * FROM $TABLE ``` -------------------------------- ### Add Upstream Remote Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Add the official unqueryvet repository as an upstream remote to your local clone. ```bash git remote add upstream https://github.com/MirrexOne/unqueryvet.git ``` -------------------------------- ### Enable Unqueryvet in VS Code Settings Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Configure VS Code to enable Unqueryvet and set its path and arguments. All rules are enabled by default. ```json { "unqueryvet.enable": true, "unqueryvet.path": "unqueryvet-lsp", "unqueryvet.args": [], "unqueryvet.trace.server": "off" } ``` -------------------------------- ### goqu: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Use `Select()` with explicit column names instead of `goqu.Star()` or `SelectAll()` for targeted data retrieval. ```go goqu.From("users").Select("id", "name", "email") ``` -------------------------------- ### Force-Enable SQL Injection Detection Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Use the -sqli flag to enable SQL injection detection, overriding the configuration. ```bash $ unqueryvet -sqli ./... ``` -------------------------------- ### rel: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md When using `rel`, specify the columns to retrieve using `rel.Select()` to avoid loading all columns by default. ```go repo.Find(ctx, &user, rel.Select("id", "name", "email")) ``` -------------------------------- ### Jet: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md In Jet, use `SELECT()` with explicit column references instead of `User.AllColumns` to retrieve specific fields. ```go stmt := SELECT(User.ID, User.Name, User.Email).FROM(User) ``` -------------------------------- ### Create Feature Branch Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Create a new branch for your feature or bug fix. Use a descriptive name for the branch. ```bash git checkout -b feature/your-feature-name ``` -------------------------------- ### Squirrel: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Use `Select()` with explicit column names instead of `Select("*")` for better performance and clarity. Ensure columns are specified when selecting from a table. ```go sq.Select("id", "name", "email").From("users") ``` -------------------------------- ### PGX: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md When executing queries with PGX, specify the desired columns in the SQL string instead of using `SELECT *`. ```go rows, err := conn.Query(ctx, "SELECT id, name, email FROM users") ``` -------------------------------- ### Show Analysis Statistics Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Append the -stats flag to display a summary of the analysis, including file counts, package loads, issue breakdowns, and duration. ```bash $ unqueryvet -stats ./... ``` -------------------------------- ### SQL Builder Specific Rules Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md These rules are tailored for specific SQL builders. The first targets GORM Raw() calls to discourage SELECT *, while the second addresses Squirrel's Select and Columns methods, warning against wildcard usage. ```yaml custom-rules: - id: gorm-raw-query pattern: $DB.Raw($QUERY) when: | builder == "gorm" && contains(query, "SELECT *") message: "Avoid SELECT * in GORM Raw() calls" severity: warning fix: "Use db.Select(columns).Find() instead of Raw()" - id: squirrel-columns-star patterns: - $VAR.Select("*") - $VAR.Columns("*") when: builder == "squirrel" message: "Avoid wildcard in Squirrel Select/Columns" severity: warning ``` -------------------------------- ### Add Configuration for New SQL Builder Source: https://github.com/mirrexone/unqueryvet/blob/main/CONTRIBUTING.md Include a boolean field for your new SQL builder in the `SQLBuildersConfig` struct and set its default value. This allows users to enable or disable the builder via configuration. ```go type SQLBuildersConfig struct { // ... existing fields ... YourBuilder bool `yaml:"yourbuilder"` } func DefaultSQLBuildersConfig() SQLBuildersConfig { return SQLBuildersConfig{ // ... existing defaults ... YourBuilder: true, } } ``` -------------------------------- ### Configure Unqueryvet in golangci-lint Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md Adds Unqueryvet to your .golangci.yml configuration file to enable it as a linter. Ensures SQL builder checks are enabled. ```yaml version: "2" linters: enable: - unqueryvet settings: unqueryvet: check-sql-builders: true ``` -------------------------------- ### GitLab CI for SQL Linting Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md This GitLab CI configuration uses the Unqueryvet Docker image to perform SQL linting. It runs the linter with specific flags for merge request events. ```yaml sql-lint: image: ghcr.io/mirrexone/unqueryvet:latest script: - unqueryvet -quiet -n1 -sqli -tx-leak ./... rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" ``` -------------------------------- ### Force-Enable N+1 Query Detection Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Use the -n1 flag to enable N+1 query detection, even if it's disabled in the configuration. ```bash $ unqueryvet -n1 ./... ``` -------------------------------- ### Customize Built-in Rule Severity and Whitelist SQL Patterns Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md Configure the severity of built-in rules like 'select-star' and 'n1-queries', and whitelist specific SQL patterns to prevent warnings. Rules can be set to 'error', 'warning', 'info', or 'ignore'. ```yaml rules: select-star: warning n1-queries: warning sql-injection: error allow: - "COUNT(*)" ``` -------------------------------- ### Ent: Select specific columns Source: https://github.com/mirrexone/unqueryvet/blob/main/README.md In Ent, use the `Select()` method with explicit field selectors to retrieve only the necessary columns, rather than relying on the default `SELECT *` behavior. ```go users, err := client.User.Query(). Select(user.FieldID, user.FieldName, user.FieldEmail). All(ctx) ``` -------------------------------- ### Configure Built-in Rule Severity and Ignore File Patterns Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md Set the severity for built-in rules and specify file patterns using glob syntax to ignore certain files during analysis. This includes test files, vendor directories, and mock generated files. ```yaml rules: select-star: error # error | warning | info | ignore n1-queries: warning sql-injection: error ignore: - "*_test.go" - "testdata/**" - "vendor/**" - "mock_*.go" allow: - "COUNT(*)" - "information_schema.*" - "pg_catalog.*" ``` -------------------------------- ### SELECT * Pattern with Schema Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/DSL.md Matches SELECT * queries that include a schema prefix. This is useful for distinguishing tables across different schemas. ```yaml pattern: SELECT * FROM $TABLE # Matches: SELECT * FROM public.users ``` -------------------------------- ### Unqueryvet Permissive Mode Configuration Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Sets diagnostic severity to 'warning' and disables several core analysis checks for a more permissive linting approach. ```yaml severity: warning check-sql-builders: false check-aliased-wildcard: false check-string-concat: false ``` -------------------------------- ### Unqueryvet Strict Mode Configuration Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Enables 'error' severity and turns on all core analysis checks for a strict linting environment. ```yaml severity: error check-sql-builders: true check-aliased-wildcard: true check-string-concat: true check-format-strings: true check-string-builder: true check-subqueries: true ``` -------------------------------- ### Git Pre-commit Hook Script Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md A bash script for a Git pre-commit hook that runs Unqueryvet to ensure code quality before committing. ```bash # .git/hooks/pre-commit echo "Running unqueryvet..." if ! unqueryvet -quiet ./...; then echo "unqueryvet found issues. Commit aborted." echo "Run 'unqueryvet -verbose ./...' for details." exit 1 fi echo "unqueryvet passed" ``` -------------------------------- ### Enable Interactive Fix Mode Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/CLI_FEATURES.md Launch Unqueryvet in interactive fix mode using the -fix flag to resolve issues directly within the terminal UI. ```bash $ unqueryvet -fix ./... ``` -------------------------------- ### Enable Verbose Logging in VS Code Source: https://github.com/mirrexone/unqueryvet/blob/main/docs/IDE_INTEGRATION.md Configure VS Code to enable verbose logging for the Unqueryvet Language Server Protocol (LSP) for debugging purposes. ```json { "unqueryvet.enable": true, "unqueryvet.path": "unqueryvet-lsp", "unqueryvet.trace.server": "verbose" } ```