### Install PHP Extensions for Database Access Source: https://github.com/seaql/sea-schema/blob/master/tests/sakila/Readme.md Installs essential PHP extensions for interacting with MySQL and PostgreSQL databases using the apt package manager. These extensions are prerequisites for database connectivity in PHP applications. ```sh sudo apt install php-mysql php-pgsql ``` -------------------------------- ### Install Project Dependencies with Composer Source: https://github.com/seaql/sea-schema/blob/master/tests/sakila/Readme.md Installs all project dependencies defined in the composer.json file. Composer is a dependency manager for PHP, ensuring all required libraries are available for the project to run. ```sh composer install ``` -------------------------------- ### Dump Database Schema using mysqldump Source: https://github.com/seaql/sea-schema/blob/master/tests/sakila/Readme.md Dumps the schema of the 'sakila' database without any data. This command uses mysqldump with specific options to exclude data, options, quoted names, and character set information, aiming to reproduce the original SQL structure. ```sh mysqldump sakila --no-data --skip-opt --skip-quote-names --skip-set-charset ``` -------------------------------- ### Generate Schema JSON File Source: https://github.com/seaql/sea-schema/blob/master/tests/sakila/Readme.md Executes the main PHP script (index.php) and redirects its output to a schema.json file. This command is used to generate the database schema in JSON format. ```sh php index.php > schema.json ``` -------------------------------- ### Check Table/Column/Index Existence with SchemaProbe Source: https://context7.com/seaql/sea-schema/llms.txt Demonstrates using `SchemaProbe` to generate SQL queries for checking the existence of tables, columns, and indexes in MySQL, PostgreSQL, and SQLite databases. It utilizes specific query builders for each database type. ```rust use sea_schema::probe::SchemaProbe; use sea_schema::mysql::MySql; use sea_schema::postgres::Postgres; use sea_schema::sqlite::Sqlite; use sea_schema::sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, SqliteQueryBuilder}; fn main() { // MySQL schema probe let mysql = MySql; // Generate query to check if table exists let query = mysql.has_table("users"); let sql = query.to_string(MysqlQueryBuilder); println!("{}", sql); // SELECT COUNT(*) > 0 AS `has_table` FROM ( // SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` // WHERE DATABASE() = `TABLES`.`TABLE_SCHEMA` AND `TABLE_NAME` = 'users' // ) AS `subquery` // Generate query to check if column exists let query = mysql.has_column("users", "email"); let sql = query.to_string(MysqlQueryBuilder); println!("{}", sql); // SELECT COUNT(*) > 0 AS `has_column` FROM `information_schema`.`COLUMNS` // WHERE DATABASE() = `COLUMNS`.`TABLE_SCHEMA` // AND `TABLE_NAME` = 'users' AND `COLUMN_NAME` = 'email' // Generate query to check if index exists let query = mysql.has_index("users", "idx_email"); let sql = query.to_string(MysqlQueryBuilder); println!("{}", sql); // PostgreSQL schema probe let postgres = Postgres; let query = postgres.has_table("users"); let sql = query.to_string(PostgresQueryBuilder); println!("{}", sql); // SQLite schema probe let sqlite = Sqlite; let query = sqlite.has_table("users"); let sql = query.to_string(SqliteQueryBuilder); println!("{}", sql); } ``` -------------------------------- ### Discover PostgreSQL Schema with SeaSchema Source: https://context7.com/seaql/sea-schema/llms.txt Connects to a PostgreSQL database using sqlx and discovers its schema, including tables, columns, constraints, and custom enum types. It demonstrates accessing schema details and also shows how to specifically discover only enum types. Requires a running PostgreSQL instance and the 'sqlx' crate with the 'runtime-tokio-rustls' and 'postgres' features. ```rust use sea_schema::postgres::discovery::SchemaDiscovery; use sqlx::PgPool; #[tokio::main] async fn main() -> Result<(), sqlx::Error> { // Connect to PostgreSQL database let pool = PgPool::connect("postgres://user:password@localhost/mydb").await?; // Create schema discovery for the "public" schema let schema_discovery = SchemaDiscovery::new(pool, "public"); // Discover the complete schema let schema = schema_discovery.discover().await?; println!("Schema: {}", schema.schema); // Access discovered enum types for enum_def in &schema.enums { println!("Enum: {}", enum_def.typename); println!(" Values: {:?}", enum_def.values); } // Access discovered tables for table in &schema.tables { println!("Table: {}", table.info.name); // Access columns with PostgreSQL-specific types for column in &table.columns { println!(" Column: {} ({:?})", column.name, column.col_type); } // Access constraints (PostgreSQL-specific) for pk in &table.primary_key_constraints { println!(" Primary Key: {:?}", pk.columns); } for unique in &table.unique_constraints { println!(" Unique Constraint: {} on {:?}", unique.name, unique.columns); } for check in &table.check_constraints { println!(" Check Constraint: {}", check.name); } for fk in &table.reference_constraints { println!(" Foreign Key: {} -> {}", fk.name, fk.foreign_table); } } // Discover only enum types let enums = schema_discovery.discover_enums().await?; for enum_def in enums { println!("Discovered enum: {} with values {:?}", enum_def.typename, enum_def.values); } Ok(()) } ``` -------------------------------- ### SQL Table Definition for film_actor Source: https://github.com/seaql/sea-schema/blob/master/README.md This snippet shows the SQL CREATE TABLE statement for the 'film_actor' table, defining its columns, primary key, indexes, and foreign key constraints. It serves as the input for schema discovery. ```sql CREATE TABLE film_actor ( actor_id SMALLINT UNSIGNED NOT NULL, film_id SMALLINT UNSIGNED NOT NULL, last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (actor_id,film_id), KEY idx_fk_film_id (`film_id`), CONSTRAINT fk_film_actor_actor FOREIGN KEY (actor_id) REFERENCES actor (actor_id) ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT fk_film_actor_film FOREIGN KEY (film_id) REFERENCES film (film_id) ON DELETE RESTRICT ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` -------------------------------- ### Discover MySQL Schema with SeaSchema Source: https://context7.com/seaql/sea-schema/llms.txt Connects to a MySQL database using sqlx and discovers its complete schema, including tables, columns, indexes, and foreign keys. It then iterates through these discovered elements and prints their details. Requires a running MySQL instance and the 'sqlx' crate with the 'runtime-tokio-rustls' and 'mysql' features. ```rust use sea_schema::mysql::discovery::SchemaDiscovery; use sqlx::MySqlPool; #[tokio::main] async fn main() -> Result<(), sqlx::Error> { // Connect to MySQL database let pool = MySqlPool::connect("mysql://root:password@localhost/mydb").await?; // Create schema discovery instance for a specific schema/database let schema_discovery = SchemaDiscovery::new(pool, "mydb"); // Discover the complete schema let schema = schema_discovery.discover().await?; // Access discovered tables for table in &schema.tables { println!("Table: {}", table.info.name); println!(" Engine: {:?}", table.info.engine); println!(" Charset: {:?}", table.info.char_set); // Access columns for column in &table.columns { println!(" Column: {} ({:?})", column.name, column.col_type); println!(" Nullable: {}", column.null); println!(" Key: {:?}", column.key); println!(" Auto Increment: {}", column.extra.auto_increment); } // Access indexes for index in &table.indexes { println!(" Index: {} (unique: {})", index.name, index.unique); for part in &index.parts { println!(" Column: {} ({:?})", part.column, part.order); } } // Access foreign keys for fk in &table.foreign_keys { println!(" FK: {} -> {}.{:?}", fk.name, fk.referenced_table, fk.referenced_columns); println!(" On Delete: {:?}, On Update: {:?}", fk.on_delete, fk.on_update); } } Ok(()) } ``` -------------------------------- ### SeaSchema Feature Configuration in Cargo.toml Source: https://context7.com/seaql/sea-schema/llms.txt Configures SeaSchema features in Cargo.toml for specific database backends and runtimes. This allows customization of SeaSchema's capabilities, such as database support (MySQL, PostgreSQL, SQLite), runtime integration (Tokio, async-std), and additional features like discovery, writing, probing, and Serde support. ```toml # Cargo.toml [dependencies] # Full MySQL support with Tokio runtime and native TLS sea-schema = { version = "0.16", features = [ "mysql", "discovery", "writer", "probe", "sqlx-mysql", "runtime-tokio-native-tls", "with-serde" ] } # PostgreSQL with async-std runtime and rustls sea-schema = { version = "0.16", features = [ "postgres", "discovery", "writer", "sqlx-postgres", "runtime-async-std-rustls" ] } # SQLite only (minimal) sea-schema = { version = "0.16", default-features = false, features = ["sqlite", "discovery", "sqlx-sqlite", "runtime-tokio"] } # All databases with all features sea-schema = { version = "0.16", features = [ "default", "sqlx-all", "runtime-tokio-native-tls", "with-serde", "debug-print" ] } ``` -------------------------------- ### Discover SQLite Schema Source: https://context7.com/seaql/sea-schema/llms.txt Discovers SQLite database schema including tables, columns, indexes, and foreign keys. It connects to a SQLite database, discovers its schema, and then iterates through the discovered tables, columns, foreign keys, and indexes, printing their details. ```rust use sea_schema::sqlite::discovery::{SchemaDiscovery, DiscoveryResult}; use sea_schema::sqlx_types::SqlitePool; #[tokio::main] async fn main() -> DiscoveryResult<()> { // Connect to SQLite database (file or in-memory) let pool = SqlitePool::connect("sqlite:./mydb.sqlite").await?; // Or for in-memory: SqlitePool::connect("sqlite::memory:").await?; // Create schema discovery instance let schema_discovery = SchemaDiscovery::new(pool); // Discover the complete schema let schema = schema_discovery.discover().await?; // Access discovered tables for table in &schema.tables { println!("Table: {}", table.name); // Access columns for column in &table.columns { println!(" Column: {} ({:?})", column.name, column.col_type); println!(" Primary Key: {}", column.is_primary_key); println!(" Auto Increment: {}", column.is_auto_increment); } // Access foreign keys for fk in &table.foreign_keys { println!(" FK: {:?} -> {}.{:?}", fk.columns, fk.foreign_table, fk.foreign_columns); } // Access unique constraints for constraint in &table.unique_constraints { println!(" Unique: {:?}", constraint.columns); } } // Access discovered indexes (separate from tables in SQLite) for index in &schema.indexes { println!("Index: {} on table {} ({:?})", index.name, index.table_name, index.columns); } Ok(()) } ``` -------------------------------- ### JSON Serialization with Serde in Rust Source: https://context7.com/seaql/sea-schema/llms.txt Enables JSON serialization and deserialization of schema definitions using the `with-serde` feature in SeaSchema. This allows for easy storage, transfer, or manipulation of schema information as JSON. It requires the `serde_json` crate and the `with-serde` feature enabled in `sea-schema`. ```rust // Cargo.toml: // [dependencies] // sea-schema = { version = "0.16", features = ["with-serde", "mysql", "discovery"] } use sea_schema::mysql::discovery::SchemaDiscovery; use sqlx::MySqlPool; #[tokio::main] async fn main() -> Result<(), Box> { let pool = MySqlPool::connect("mysql://root:password@localhost/mydb").await?; let schema = SchemaDiscovery::new(pool, "mydb").discover().await?; // Serialize schema to JSON let json = serde_json::to_string_pretty(&schema)?; println!("{}", json); // Output example: // { // "schema": "mydb", // "system": { // "version": "8.0.32", // "system": "MySQL" // }, // "tables": [ // { // "info": { // "name": "users", // "engine": "InnoDB", // "auto_increment": 100, // "char_set": "utf8mb4", // "collation": "utf8mb4_0900_ai_ci", // "comment": "" // }, // "columns": [...], // "indexes": [...], // "foreign_keys": [...] // } // ] // } // Deserialize schema from JSON let restored: sea_schema::mysql::def::Schema = serde_json::from_str(&json)?; println!("Restored {} tables", restored.tables.len()); Ok(()) } ``` -------------------------------- ### Write PostgreSQL Schema with Enums to SQL Source: https://context7.com/seaql/sea-schema/llms.txt Writes PostgreSQL schema, including custom enum types, to SQL statements. It connects to a PostgreSQL database, discovers its schema, and then writes enum type definitions followed by table definitions as SQL statements. ```rust use sea_schema::postgres::discovery::SchemaDiscovery; use sea_schema::sea_query::PostgresQueryBuilder; use sqlx::PgPool; #[tokio::main] async fn main() -> Result<(), sqlx::Error> { let pool = PgPool::connect("postgres://user:password@localhost/mydb").await?; let schema_discovery = SchemaDiscovery::new(pool, "public"); let schema = schema_discovery.discover().await?; // Write enum type definitions first for enum_def in &schema.enums { let create_enum = enum_def.write(); let sql = create_enum.to_string(PostgresQueryBuilder); println!("{};", sql); } // Output: CREATE TYPE "status_type" AS ENUM ('pending', 'active', 'completed'); // Write table definitions let create_statements = schema.write(); for stmt in create_statements { let sql = stmt.to_string(PostgresQueryBuilder); println!("{};", sql); } Ok(()) } ``` -------------------------------- ### Define MySQL Column Types with Sea Schema Source: https://context7.com/seaql/sea-schema/llms.txt Illustrates how to define various MySQL column types using Sea Schema's type definitions, including attributes like length, precision, unsigned, nullability, keys, and default values. This is useful for programmatically generating table schemas. ```rust use sea_schema::mysql::def::*; fn main() { // Define a column with numeric type let id_column = ColumnInfo { name: "id".to_owned(), col_type: ColumnType::Int(NumericAttr { maximum: None, decimal: None, unsigned: Some(true), zero_fill: None, }), null: false, key: ColumnKey::Primary, default: None, extra: ColumnExtra { auto_increment: true, on_update_current_timestamp: false, generated: false, default_generated: false, }, expression: None, comment: "Primary key".to_owned(), }; // Define a VARCHAR column let name_column = ColumnInfo { name: "name".to_owned(), col_type: ColumnType::Varchar(StringAttr { length: Some(255), charset: None, collation: None, }), null: true, key: ColumnKey::NotKey, default: Some(ColumnDefault::Null), extra: ColumnExtra::default(), expression: None, comment: "".to_owned(), }; // Define a TIMESTAMP column with auto-update let updated_at = ColumnInfo { name: "updated_at".to_owned(), col_type: ColumnType::Timestamp(TimeAttr { fractional: Some(6) }), null: false, key: ColumnKey::NotKey, default: Some(ColumnDefault::CurrentTimestamp), extra: ColumnExtra { auto_increment: false, on_update_current_timestamp: true, generated: false, default_generated: true, }, expression: None, comment: "".to_owned(), }; // Define a DECIMAL column let price_column = ColumnInfo { name: "price".to_owned(), col_type: ColumnType::Decimal(NumericAttr { maximum: Some(19), decimal: Some(4), unsigned: Some(true), zero_fill: None, }), null: true, key: ColumnKey::NotKey, default: None, extra: ColumnExtra::default(), expression: None, comment: "".to_owned(), }; println!("Columns defined: {:?}, {:?}, {:?}, {:?}", id_column.name, name_column.name, updated_at.name, price_column.name); } ``` -------------------------------- ### Convert MySQL Schema to SQL Statements Source: https://context7.com/seaql/sea-schema/llms.txt Converts discovered MySQL schema back to SeaQuery `TableCreateStatement` objects that can be rendered to SQL. It connects to a MySQL database, discovers its schema, and then writes the schema as SQL CREATE TABLE statements. ```rust use sea_schema::mysql::discovery::SchemaDiscovery; use sea_schema::sea_query::MysqlQueryBuilder; use sqlx::MySqlPool; #[tokio::main] async fn main() -> Result<(), sqlx::Error> { let pool = MySqlPool::connect("mysql://root:password@localhost/sakila").await?; let schema = SchemaDiscovery::new(pool, "sakila").discover().await?; // Convert entire schema to CREATE TABLE statements let create_statements = schema.write(); for stmt in create_statements { // Render to MySQL SQL syntax let sql = stmt.to_string(MysqlQueryBuilder); println!("{};", sql); } // Or for individual tables for table in &schema.tables { let create_stmt = table.write(); let sql = create_stmt.to_string(MysqlQueryBuilder); println!("-- Table: {}", table.info.name); println!("{};", sql); } Ok(()) } // Example output for a table: // CREATE TABLE `film_actor` ( // `actor_id` smallint UNSIGNED NOT NULL, // `film_id` smallint UNSIGNED NOT NULL, // `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, // PRIMARY KEY (`actor_id`, `film_id`), // KEY `idx_fk_film_id` (`film_id`), // CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) // ON DELETE RESTRICT ON UPDATE CASCADE, // CONSTRAINT `fk_film_actor_film` FOREIGN KEY (`film_id`) REFERENCES `film` (`film_id`) // ON DELETE RESTRICT ON UPDATE CASCADE // ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ``` -------------------------------- ### Define MySQL Table Structure with Sea Schema (Rust) Source: https://context7.com/seaql/sea-schema/llms.txt This Rust code defines a complete MySQL table structure named 'orders', including its columns, primary key, secondary index, and a foreign key constraint. It then uses the Sea Schema library to generate the corresponding SQL CREATE TABLE statement. ```rust use sea_schema::mysql::def::*; use sea_schema::sea_query::MysqlQueryBuilder; fn main() { // Define a complete table let table = TableDef { info: TableInfo { name: "orders".to_owned(), engine: StorageEngine::InnoDb, auto_increment: Some(1), char_set: Some(CharSet::Utf8Mb4), collation: Some(Collation::Utf8Mb40900AiCi), comment: "Customer orders table".to_owned(), }, columns: vec![ ColumnInfo { name: "id".to_owned(), col_type: ColumnType::Int(NumericAttr { maximum: None, decimal: None, unsigned: Some(true), zero_fill: None, }), null: false, key: ColumnKey::Primary, default: None, extra: ColumnExtra { auto_increment: true, ..Default::default() }, expression: None, comment: "".to_owned(), }, ColumnInfo { name: "customer_id".to_owned(), col_type: ColumnType::Int(NumericAttr { maximum: None, decimal: None, unsigned: Some(true), zero_fill: None, }), null: false, key: ColumnKey::Multiple, default: None, extra: ColumnExtra::default(), expression: None, comment: "".to_owned(), }, ], indexes: vec![ IndexInfo { unique: true, name: "PRIMARY".to_owned(), parts: vec![IndexPart { column: "id".to_owned(), order: IndexOrder::Ascending, sub_part: None, }], nullable: false, idx_type: IndexType::BTree, comment: "".to_owned(), functional: false, }, IndexInfo { unique: false, name: "idx_customer".to_owned(), parts: vec![IndexPart { column: "customer_id".to_owned(), order: IndexOrder::Ascending, sub_part: None, }], nullable: false, idx_type: IndexType::BTree, comment: "".to_owned(), functional: false, }, ], foreign_keys: vec![ ForeignKeyInfo { name: "fk_orders_customer".to_owned(), columns: vec!["customer_id".to_owned()], referenced_table: "customers".to_owned(), referenced_columns: vec!["id".to_owned()], on_delete: ForeignKeyAction::Cascade, on_update: ForeignKeyAction::Cascade, }, ], }; // Convert to SQL using the writer let create_stmt = table.write(); let sql = create_stmt.to_string(MysqlQueryBuilder); println!("{}", sql); // Output: // CREATE TABLE `orders` ( // `id` int UNSIGNED NOT NULL AUTO_INCREMENT, // `customer_id` int UNSIGNED NOT NULL, // PRIMARY KEY (`id`), // KEY `idx_customer` (`customer_id`), // CONSTRAINT `fk_orders_customer` FOREIGN KEY (`customer_id`) // REFERENCES `customers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE // ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci } ``` -------------------------------- ### Rust Schema Discovery Result for film_actor Source: https://github.com/seaql/sea-schema/blob/master/README.md This Rust code represents the discovered schema of the 'film_actor' SQL table. It details table information, column definitions (including types, nullability, keys, and defaults), and index/foreign key configurations. ```rust TableDef { info: TableInfo { name: "film_actor", engine: InnoDb, auto_increment: None, char_set: Utf8Mb4, collation: Utf8Mb40900AiCi, comment: "", }, columns: [ ColumnInfo { name: "actor_id", col_type: SmallInt( NumericAttr { maximum: None, decimal: None, unsigned: Some(true), zero_fill: None, }, ), null: false, key: Primary, default: None, extra: ColumnExtra { auto_increment: false, on_update_current_timestamp: false, generated: false, default_generated: false, }, expression: None, comment: "", }, ColumnInfo { name: "film_id", col_type: SmallInt( NumericAttr { maximum: None, decimal: None, unsigned: Some(true), zero_fill: None, }, ), null: false, key: Primary, default: None, extra: ColumnExtra { auto_increment: false, on_update_current_timestamp: false, generated: false, default_generated: false, }, expression: None, comment: "", }, ColumnInfo { name: "last_update", col_type: Timestamp(TimeAttr { fractional: None }), null: false, key: NotKey, default: Some(ColumnDefault::CurrentTimestamp), extra: ColumnExtra { auto_increment: false, on_update_current_timestamp: true, generated: false, default_generated: true, }, expression: None, comment: "", }, ], indexes: [ IndexInfo { unique: false, name: "idx_fk_film_id", parts: [ IndexPart { column: "film_id", order: Ascending, sub_part: None, }, ], nullable: false, idx_type: BTree, comment: "", functional: false, }, IndexInfo { unique: true, name: "PRIMARY", parts: [ IndexPart { column: "actor_id", order: Ascending, sub_part: None, }, IndexPart { column: "film_id", order: Ascending, sub_part: None, }, ], nullable: false, idx_type: BTree, comment: "", functional: false, }, ], foreign_keys: [ ForeignKeyInfo { name: "fk_film_actor_actor", columns: [ "actor_id" ], referenced_table: "actor", referenced_columns: [ "actor_id" ], on_update: Cascade, on_delete: Restrict, }, ForeignKeyInfo { name: "fk_film_actor_film", columns: [ "film_id" ], referenced_table: "film", referenced_columns: [ "film_id" ], on_update: Cascade, on_delete: Restrict, }, ], } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.