Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
SeaSchema is a specialized library designed to manage database schemas for MySQL, PostgreSQL, and SQLite. Its primary purpose is to provide robust type definitions that closely map to database structures and provide utilities for automated schema discovery and SQL generation.
The system is designed to bridge the gap between live database states and programmatic representations. It allows developers to discover existing schemas, manipulate them as Rust data structures, and export them back into SeaQuery statements or raw SQL.
Sources: README.md:14-18, Cargo.toml:14-16
Core Module Architecture
The project is structured into functional modules that handle different stages of the schema lifecycle. This modular approach separates the data representation (definitions) from the logic used to acquire that data (discovery) or transform it (writer).
Functional Components
| Module | Description |
|---|---|
def | Core type definitions representing database entities (Tables, Columns, Indexes). |
query | Utilities for constructing SQL queries against INFORMATION_SCHEMA. |
parser | Logic for parsing raw query results from the database into structured definitions. |
discovery | The high-level interface used to connect to a live database and extract a complete Schema. |
writer | Logic for converting internal Schema definitions into SeaQuery statements and SQL. |
Sources: README.md:21-27, src/mysql/discovery/mod.rs:1-10
Module Relationship Diagram
The following diagram illustrates how data flows from the live database through the discovery and parsing layers into the final structured definitions.
This diagram shows the sequential flow from database inspection to code generation.
Schema Discovery Process
The discovery process is the core engine of SeaSchema. It follows a hierarchical pattern: first identifying system information, then listing tables, and finally performing deep inspection of each table's metadata.
Discovery Logic Flow
- System Discovery: Queries the database version and system-specific metadata (e.g., MariaDB vs. MySQL versions).
- Table Enumeration: Lists all tables within the target schema or database.
- Metadata Inspection: For each table, the system concurrently or sequentially discovers:
- Columns: Names, types, nullability, and default values.
- Indexes: Primary keys, unique constraints, and secondary indexes.
- Foreign Keys: Relationships and referential integrity actions (Cascade, Restrict, etc.).
Sources: src/mysql/discovery/mod.rs:46-54, src/mysql/parser/system.rs:13-18
Discovery Sequence Diagram
This sequence diagram outlines the iterative process of building a full schema representation.
Sources: src/mysql/discovery/mod.rs:36-150, sea-schema-sync/src/postgres/discovery/mod.rs:56-118
Database Specific Implementations
While the high-level API remains consistent, the underlying logic diverges to handle the nuances of different database engines.
MySQL Implementation
The MySQL module focuses on INFORMATION_SCHEMA. It handles specific MySQL attributes like ENGINE types (e.g., InnoDB), character sets, and collations. It also includes complex parsing for MySQL-specific column extras like on update CURRENT_TIMESTAMP.
Sources: src/mysql/discovery/mod.rs:88-106, src/mysql/parser/system.rs:21-35
PostgreSQL Implementation
The PostgreSQL discovery module includes additional logic for User-Defined Types (UDTs) and Enums. Before discovering tables, it queries the system catalogs for enum definitions to ensure that column types are correctly mapped to their custom enum values.
Sources: sea-schema-sync/src/postgres/discovery/mod.rs:57-65, CHANGELOG.md:11-13
Writer System
The writer module provides the inverse operation of discovery. It takes the internal TableDef or IndexInfo structures and generates sea-query objects.
Index Writing Logic
When writing an index, the system must determine if it is a Primary Key, Unique Index, or a specialized type (like FullText or Spatial). It maps internal IndexOrder (Ascending/Descending) to the appropriate SQL syntax.
// Example of index writing logic for MySQL
// Source: src/mysql/writer/index.rs:6-15
pub fn write(&self) -> IndexCreateStatement {
let mut index = Index::create();
if self.name == "PRIMARY" {
index.primary();
} else {
index.name(&self.name);
if self.unique {
index.unique();
}
}
// ... column mapping logic ...
index
}
Sources: src/mysql/writer/index.rs:4-60
Crate Features and Dependencies
SeaSchema uses Rust feature flags to manage its dependencies on various database drivers and runtimes.
| Feature | Description |
|---|---|
mysql / postgres / sqlite | Enables support for the respective database backend. |
discovery | Enables the schema discovery engine (requires parser and query). |
writer | Enables SQL/SeaQuery generation from definitions. |
sqlx-all | Integrates with the SQLx ecosystem for all supported databases. |
runtime-tokio / runtime-actix | Specifies the async runtime for discovery operations. |
Sources: Cargo.toml:39-70
Conclusion
The architecture of SeaSchema is built on a clear separation between database-agnostic definitions and database-specific discovery/writing logic. By leveraging SeaQuery as an intermediate representation, it provides a powerful toolkit for developers to treat SQL schemas as first-class Rust objects, enabling automated migrations, schema introspection, and dynamic query generation.