Lighter

repository·develop·Indexed 19 days ago

https://github.com/lighter-swift/lighter

A code-generation toolkit for Swift that provides type-safe, high-performance access to SQLite3 databases by generating Swift code directly from database schemas. It includes the Enlighter build plugin for automatic discovery of .sqlite3 and .sql files, the Generate Code for SQLite command plugin for manual generation, and the sqlite2swift tool. Lighter enables type-safe queries, transactional updates, and the option to generate code that works with the raw SQLite3 C API to avoid third-party dependencies.

Tokens
17.7K
Snippets
50
Records
83
Agent score
68%

What's inside Lighter

  1. Overview of Lighter Code Generation AST

    develop

    Lighter Code Generation AST is a simplified Abstract Syntax Tree (AST) designed specifically for code generation tasks within the Enlighter ecosystem.

    Key Characteristics:

    • Purpose-built: It is not intended to be a complete representation of the Swift language. Instead, it focuses exclusively on the subset of Swift syntax required by code generation plugins.
    • Simplicity: It is a lightweight, "simplistic" AST designed to facilitate the creation of code generation tools without the overhead of a full language parser.
  2. Overview of SQLite3Schema

    develop

    SQLite3Schema is a lightweight library designed to fetch the SQLite3 database catalog. It allows you to retrieve the schema of a SQLite3 database, including tables, views, foreign keys, and other metadata.

    Key characteristics:

    • Zero dependencies: It works directly with the SQLite3 module available on macOS and iOS.
    • Cross-platform: Includes a SQLite3 stub for Linux environments.
  3. Overview of the sqlite2swift tool

    develop

    The sqlite2swift tool is a code generator designed for SQLite databases. It can perform two primary functions:

    1. Generate Swift code based on an existing SQLite database.
    2. Generate a set of SQL source files that, when executed, create a specific SQLite database.

    It is designed to be used as part of the Enlighter plugin workflow, where it automatically runs for every applicable set of files it detects, but it can also be invoked as a standalone tool.

  4. What is Lighter

    develop

    Lighter is a Swift toolset for working with SQLite3 databases that provides type-safety down to the SQL schema. Unlike an ORM, it does not perform type mapping at runtime; instead, it generates Swift code directly from your SQL schema (or binary SQLite files).

    Key characteristics:

    • Type-safe: Generates Swift structs that mirror your database tables.
    • Fast and Dependency-free: Can be used without the optional Lighter support library.
    • Relationship-aware: Generates code to resolve database relationships.
    • Versatile: Suitable for iOS caches, Mac app documents, or server-side datasets.
  5. Overview of Lighter

    develop

    Lighter is a technology suite that applies code generation to provide type-safe access to SQLite3 databases from Swift (iOS or server-side). Unlike traditional ORMs that generate SQL from Swift code, Lighter reverses this process: it generates Swift code based on your existing SQLite schema (from .sqlite3 files or .sql scripts).

    Key benefits include:

    • Type-safety: Swift structures are generated to match your SQLite tables exactly.
    • Performance: The generated code binds directly to the SQLite API, avoiding runtime mapping overhead.
    • Dependency-free options: The generator can produce code that uses only the raw SQLite3 API, allowing you to avoid shipping third-party library dependencies.
  6. Understand Lighter performance characteristics

    develop

    Lighter is designed for high-performance database operations by directly and statically binding SQLite prepared statements to generated structures. This approach allows Lighter to achieve performance levels comparable to raw SQLite API bindings, significantly outperforming other popular Swift SQLite libraries like GRDB and SQLite.swift, especially when those libraries use Codable for mapping.

    Performance Comparison Summary

    In benchmark tests loading the Northwind "Orders" table (16K records) 500 times:

    • Lighter (High-level API): Serves as the baseline (~8 seconds).
    • Enlighter (Raw SQLite API Bindings): ~20% faster than Lighter.
    • GRDB (Handwritten Mapping): ~50% slower than Lighter.
    • SQLite.swift (Handwritten Mapping): >3x slower than Lighter.
    • GRDB (Codable): >6x slower than Lighter.
    • SQLite.swift (Codable): >19x slower than Lighter.

    Key Recommendation: To maintain high performance, avoid using Codable for database mapping; use Lighter's generated structures instead.

  7. Explore Northwind implementation demos

    develop

    There are two primary reference implementations using the Northwind database and Lighter:

    • NorthwindWebAPI: A server-side Swift example that exposes the database via JSON API endpoints and provides HTML pages for data visualization.
    • NorthwindSwiftUI: A client-side SwiftUI example demonstrating how to browse the database using Lighter's async/await support.
  8. What is the GenerateInternalVariadics tool?

    develop

    The GenerateInternalVariadics tool is an internal utility used exclusively by the Lighter package. It is not a standalone product for end-users.

    Its purpose is to automate the generation of the Lighter/Operations/GeneratedVariadicOperations.swift file. This generated file contains variadic versions of core database operations like select and update, allowing for flexible, multi-column queries with type safety.

  9. Filter records using Swift closures vs SQL Predicates

    develop

    Lighter offers two distinct ways to filter records. Choosing the right one depends on whether you prioritize flexibility or performance.

    1. Filtering using Swift Closures (Flexible but Slower)

    This method uses a Swift closure that receives a fully populated model. It allows for arbitrary Swift code (like complex Unicode normalization), but it is slower because SQLite cannot use indices; the database must fill the full record before filtering.

    2. Filtering using SQL Predicates (Fast and Type-safe)

    This method uses SQLPredicate to generate real SQL. It is fast because it allows SQLite to use indices. It is also completely type-safe; the compiler will prevent you from comparing incompatible types (e.g., comparing a number to a string).

    Comparison Summary

    FeatureSwift ClosureSQL Predicate
    PerformanceSlower (Full record fetch)Faster (Uses indices)
    FlexibilityHighest (Any Swift code)High (SQL-compatible logic)
    Type SafetyStandard SwiftStrict SQL-type binding
    // Method 1: Swift Closure (Flexible)
    let products = try database.products.filter { product in
      product.name.lowercased().contains("e")
    }
    
    // Method 2: SQL Predicate (Fast/Type-safe)
    let products = try database.products.fetch { product in
      product.name.contains("e") && product.age < 10
    }
  10. Lighter Toolkit Components

    develop

    The Lighter toolset is composed of four main components designed for different workflows:

    1. Lighter (Support Library): An optional library intended to be used alongside generated code to provide enhanced functionality (like async/await support). It is not meant to be used as a standalone library.
    2. Enlighter (Swift Build Plugin): A Swift 5.6 build plugin for Xcode and Swift Package Manager that automates code generation during the build process.
    3. Generate Code for SQLite3 (Swift Command Plugin): A Swift 5.6 command plugin for Xcode and Swift Package Manager.
    4. sqlite2swift (CLI Tool): A tool for generating SQLite code in environments that do not yet support Xcode 14 or Swift 5.6 (the resulting generated code is compatible with earlier versions).

    Additionally, there is a macOS application called Code for SQLite3 available on the App Store that provides a GUI for the same generation capabilities as sqlite2swift.

  11. Understand the SQLite3 module naming and Darwin compatibility

    develop

    The SQLite3 module is designed to provide a consistent interface across platforms. While Darwin platforms (macOS, iOS, etc.) have SQLite3 pre-bundled, this module embeds the system module to support Linux and other environments.

    Note that while this is functionally similar to the CSQLite3 module provided by ZeeQL, it is named SQLite3 here to maintain compatibility with Darwin-based naming conventions.