Drops.SQL.Compiler (drops_relation v0.1.0)

View Source

Compiler behavior and macro for processing database introspection ASTs.

This module provides a macro-based compiler framework that transforms database introspection ASTs into structured Drops.SQL.Database.* structs. It implements a visitor pattern where each AST node type is processed by a corresponding visit/2 function.

Architecture

The compiler uses a macro-based approach to generate visitor functions that process different types of AST nodes. Each database adapter has its own compiler module that uses this macro and implements adapter-specific type conversions and processing logic.

Visitor Pattern

The generated visit/2 functions follow a consistent pattern:

  • visit({:table, components}, opts) - Processes table AST nodes
  • visit({:column, components}, opts) - Processes column AST nodes
  • visit({:foreign_key, components}, opts) - Processes foreign key AST nodes
  • visit({:index, components}, opts) - Processes index AST nodes
  • visit({:identifier, name}, opts) - Processes identifier nodes
  • visit({:type, type}, opts) - Processes type nodes (adapter-specific)
  • visit({:meta, meta}, opts) - Processes metadata nodes

Generated Functions

When a module uses this compiler, the following functions are generated:

  • opts/0 - Returns the compiler options
  • process/2 - Main entry point for processing AST nodes
  • visit/2 - Visitor functions for different AST node types

Usage

defmodule MyCompiler do
  use Drops.SQL.Compiler

  # Implement adapter-specific type conversion
  def visit({:type, "varchar"}, _opts), do: :string
  def visit({:type, "integer"}, _opts), do: :integer
  # ... other type mappings
end

# Process a table AST
ast = {:table, {{:identifier, "users"}, columns, foreign_keys, indices}}
table = MyCompiler.process(ast, adapter: :my_adapter)

Implementing Compilers

To create a new compiler:

  1. Use the Drops.SQL.Compiler macro
  2. Implement visit({:type, type}, opts) for your database's type system
  3. Optionally override other visitor functions for custom behavior
  4. Optionally implement visit({:default, value}, opts) for default value processing

AST Structure

The compiler expects AST nodes in the following format:

# Table
{:table, {name, columns, foreign_keys, indices}}

# Column
{:column, {name, type, meta}}

# Foreign Key
{:foreign_key, {name, columns, referenced_table, referenced_columns, meta}}

# Index
{:index, {name, columns, meta}}

# Identifier
{:identifier, string_name}

# Type (adapter-specific)
{:type, type_value}

# Metadata
{:meta, metadata_map}

Summary

Functions

Macro for implementing database compiler modules.

Functions

__using__(opts)

(macro)

Macro for implementing database compiler modules.

This macro sets up the necessary aliases and compilation hooks to generate visitor functions for processing database AST nodes.

Options

Any options passed to the macro are stored and made available via the generated opts/0 function.

Generated Functions

  • opts/0 - Returns the compiler options
  • process/2 - Main entry point for AST processing
  • visit/2 - Visitor functions for different AST node types

Example

defmodule MyCompiler do
  use Drops.SQL.Compiler, some_option: :value

  # Implement adapter-specific type mappings
  def visit({:type, "text"}, _opts), do: :string
end

extract_from_suffixed(value, suffix)

sql_function?(value)