sqlc

repository·main·Indexed 12 days ago

https://github.com/sqlc-dev/sqlc

A SQL compiler that generates type-safe code from SQL queries. It supports official language generators for Go, Kotlin, Python, and TypeScript, and allows for additional functionality via WASM plugins. The tool bridges the gap between raw SQL and application-level programming by generating type-safe interfaces based on defined database schemas and queries.

Tokens
31.6K
Snippets
132
Records
163
Agent score
95%

What's inside sqlc

  1. Privacy and data collection for the sqlc CLI

    main
    The sqlc command line tool is designed to be privacy-preserving. It does not collect any user information, does not send crash reports to third parties, and does not gather anonymous aggregate user behavior analytics. It performs no fingerprinting or tracking.
  2. What is sqlc and how does it work?

    main

    sqlc is a SQL compiler that generates fully type-safe idiomatic Go code from your SQL queries. This eliminates the need to write boilerplate SQL querying code manually.

    The workflow consists of three steps:

    1. Write SQL queries: Define your database schema and queries in SQL.
    2. Run sqlc: Execute the compiler to generate Go code that provides type-safe interfaces for those queries.
    3. Write application code: Call the methods generated by sqlc within your Go application.
  3. Understand the default naming scheme for generated structs

    main

    By default, sqlc generates Go structs based on your database tables. If a table name is pluralized (e.g., authors), sqlc will attempt to use the singular form of that name for the struct name (e.g., Author).

    CREATE TABLE authors (
      id   SERIAL PRIMARY KEY,
      name text   NOT NULL
    );
    package db
    
    // Struct names use the singular form of table names
    type Author struct {
    	ID   int
    	Name string
    }
  4. How sqlc works

    main

    sqlc is a SQL compiler that generates type-safe code from your SQL queries. The workflow consists of three steps:

    1. Write SQL: Define your database schema and write your queries in standard SQL.
    2. Run sqlc: Execute the sqlc compiler to generate type-safe interfaces and code based on those queries.
    3. Use generated code: Write your application logic by calling the generated functions, ensuring type safety between your application and the database.
  5. How sqlc handles Null values in structs

    main

    For nullable columns in a struct, sqlc uses the appropriate null types from the database/sql or pgx packages (e.g., sql.NullString for nullable TEXT).

    CREATE TABLE authors (
      id   SERIAL PRIMARY KEY,
      name text   NOT NULL,
      bio  text
    );
    type Author struct {
    	ID   int
    	Name string
    	Bio  sql.NullString
    }
  6. How sqlc maps UUIDs to Go

    main

    sqlc uses github.com/google/uuid for UUID support. If you are using the pgx/v5 driver, it uses pgtype.UUID.

    MySQL UUID Workaround: MySQL does not have a native uuid type. If you store UUIDs as BINARY(16) using UUID_TO_BIN, sqlc defaults to mapping them to sql.NullString. To map these to uuid.UUID automatically, you must use an overrides configuration in your sqlc.json file.

    {
      "overrides": [
        {
          "column": "*.uuid",
          "go_type": "github.com/google/uuid.UUID"
        }
      ]
    }
  7. How WithTx works in generated sqlc code

    main

    The WithTx method is a part of the Queries struct generated by sqlc. It allows for dependency injection of a transaction into the query runner.

    Internally, sqlc generates a DBTX interface that both *sql.DB (or connection pools) and *sql.Tx (transactions) satisfy. When you call WithTx(tx), the returned Queries struct uses the transaction as its underlying db field, ensuring all subsequent method calls on that instance are executed within the context of that specific transaction.

    type DBTX interface {
    	ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
    	PrepareContext(context.Context, string) (*sql.Stmt, error)
    	QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
    	QueryRowContext(context.Context, string, ...interface{}) *sql.Row
    }
    
    func (q *Queries) WithTx(tx DBTX) *Queries {
    	return &Queries{
    		db: tx,
    	}
    }
  8. Use `EXPLAIN` output in lint rules

    main

    If you have a database connection configured (using a uri or managed database), sqlc vet can use the output of EXPLAIN commands to create advanced lint rules.

    • PostgreSQL: Uses EXPLAIN (ANALYZE false, VERBOSE, COSTS, SETTINGS, BUFFERS, FORMAT JSON) ... and populates the postgresql.explain variable.
    • MySQL: Uses EXPLAIN FORMAT=JSON ... and populates the mysql.explain variable.

    Important Requirements:

    • You must have a database connection configured in your sqlc.yaml.
    • The database schema must be up-to-date. sqlc does not run migrations automatically. Use your migration tool first, or use managed databases to let sqlc handle ephemeral database creation.

    Example Rules:

    rules:
    - name: postgresql-query-too-costly
      message: "Query cost estimate is too high"
      rule: "postgresql.explain.plan.total_cost > 1.0"
    - name: postgresql-no-seq-scan
      message: "Query plan results in a sequential scan"
      rule: "postgresql.explain.plan.node_type == 'Seq Scan'"
    - name: mysql-query-too-costly
      message: "Query cost estimate is too high"
      rule: "has(mysql.explain.query_block.cost_info) && double(mysql.explain.query_block.cost_info.query_cost) > 2.0"
    - name: mysql-must-use-primary-key
      message: "Query plan doesn't use primary key"
      rule: "has(mysql.explain.query_block.table.key) && mysql.explain.query_block.table.key != 'PRIMARY'"
  9. Data collection in sqlc distribution channels

    main
    When installing sqlc via package managers like Homebrew or Snapcraft, be aware that these specific package managers and their associated command-line tools may collect usage metrics. However, sqlc itself remains non-tracking. Users can always choose to download sqlc directly from a stable URL to avoid package manager telemetry.
  10. How sqlc parses database schemas

    main

    sqlc generates code by parsing CREATE TABLE and ALTER TABLE statements. It tracks changes to the schema (adding columns, dropping columns, or renaming tables) to produce the correct corresponding Go structs and types.

    CREATE TABLE authors (
      id          SERIAL PRIMARY KEY,
      birth_year  int    NOT NULL
    );
    
    ALTER TABLE authors ADD COLUMN bio text NOT NULL;
    ALTER TABLE authors DROP COLUMN birth_year;
    ALTER TABLE authors RENAME TO writers;