114 lines
5.3 KiB
Rust
114 lines
5.3 KiB
Rust
mod column_alter;
|
|
mod column_format;
|
|
mod columns;
|
|
mod comments;
|
|
mod create_table;
|
|
mod dialect;
|
|
mod foreign_keys;
|
|
mod indexes;
|
|
mod mysql_engine;
|
|
mod owner;
|
|
mod partitions;
|
|
mod triggers;
|
|
mod types;
|
|
mod util;
|
|
mod validation;
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
pub use column_alter::build_single_column_alter_sql;
|
|
pub use create_table::build_create_table_sql;
|
|
pub use owner::build_table_owner_change_sql;
|
|
pub use partitions::{build_create_partitioned_table_sql, build_table_partition_operation_sql};
|
|
pub use types::*;
|
|
|
|
pub use column_alter::{
|
|
build_sqlserver_alter_column_preserving_default_sql, build_sqlserver_drop_default_constraint_sql,
|
|
};
|
|
pub use comments::{build_sqlserver_column_comment_sql, build_sqlserver_table_comment_sql};
|
|
pub use util::{oracle_new_object_reference, sqlserver_unicode_string_literal};
|
|
|
|
use crate::models::connection::DatabaseType;
|
|
|
|
use column_format::strip_inherited_mysql_column_charsets;
|
|
use columns::{build_column_sql, validate_primary_key_change_scope};
|
|
use comments::build_table_comment_sql;
|
|
use foreign_keys::build_foreign_key_sql;
|
|
use indexes::build_index_sql;
|
|
use mysql_engine::{build_mysql_engine_change_sql, validate_mysql_engine};
|
|
use triggers::build_trigger_sql;
|
|
use validation::validate_concurrent_index_scope;
|
|
pub use validation::validate_draft;
|
|
|
|
pub fn build_table_structure_change_sql(mut options: TableStructureSqlOptions) -> TableStructureSqlResult {
|
|
let mysql_engine_errors = validate_mysql_engine(&options);
|
|
if !mysql_engine_errors.is_empty() {
|
|
return TableStructureSqlResult { statements: Vec::new(), warnings: mysql_engine_errors };
|
|
}
|
|
// GaussDB M-mode uses MySQL-compatible SQL dialect with backtick quoting.
|
|
// Map to StructureDialect::Mysql so DDL is generated correctly.
|
|
if options.is_gaussdb_m_mode {
|
|
options.database_type = Some(DatabaseType::Mysql);
|
|
}
|
|
strip_inherited_mysql_column_charsets(&mut options);
|
|
let primary_key_errors = validate_primary_key_change_scope(&options);
|
|
if !primary_key_errors.is_empty() {
|
|
return TableStructureSqlResult { statements: Vec::new(), warnings: primary_key_errors };
|
|
}
|
|
// Fail closed: an unsupported concurrent-index request (existing index, or
|
|
// partitioned parent table) must never degrade into blocking index DDL
|
|
// behind the caller's back, so the whole plan is refused up front.
|
|
let concurrent_errors = validate_concurrent_index_scope(&options);
|
|
if !concurrent_errors.is_empty() {
|
|
return TableStructureSqlResult { statements: Vec::new(), warnings: concurrent_errors };
|
|
}
|
|
let mut warnings = validate_draft(&options);
|
|
let mut statements = build_column_sql(&options, &mut warnings);
|
|
statements.extend(build_index_sql(&options, &mut warnings));
|
|
statements.extend(build_foreign_key_sql(&options, &mut warnings));
|
|
statements.extend(build_trigger_sql(&options, &mut warnings));
|
|
statements.extend(build_table_comment_sql(&options, &mut warnings));
|
|
statements.extend(build_mysql_engine_change_sql(&options));
|
|
TableStructureSqlResult { statements, warnings }
|
|
}
|
|
|
|
/// Whether this engine's structure editor can generate `COMMENT ON`/inline
|
|
/// comment DDL for tables and columns — a DDL-generation capability, not an
|
|
/// introspection one. The documentation collector uses it as a heuristic for
|
|
/// "can this engine report comments at all", but the two questions can
|
|
/// diverge: IRIS supports `%DESCRIPTION` while *defining* a table or column,
|
|
/// but DBX's editor cannot ALTER an existing one, so this returns `false`
|
|
/// for IRIS even though IRIS still reports descriptions on introspection.
|
|
/// Callers using this as an introspection signal must corroborate it against
|
|
/// what was actually collected rather than trust the flag alone.
|
|
pub fn supports_comments(database_type: crate::models::connection::DatabaseType) -> bool {
|
|
dialect::capabilities_for(Some(database_type), None).comment
|
|
}
|
|
|
|
/// Whether this engine's structure editor can generate foreign key DDL — a
|
|
/// DDL-generation capability, not an introspection one, used here as a
|
|
/// heuristic for "does this engine report foreign key metadata at all".
|
|
/// Engines like ClickHouse and Doris genuinely report none, so their ER
|
|
/// diagrams have no edges by necessity rather than by accident, but a
|
|
/// mismatch analogous to the IRIS comment case is possible for any future
|
|
/// engine where DDL support and introspection support diverge — callers
|
|
/// should corroborate against what was actually collected.
|
|
pub fn supports_foreign_keys(database_type: crate::models::connection::DatabaseType) -> bool {
|
|
dialect::capabilities_for(Some(database_type), None).foreign_key
|
|
}
|
|
|
|
/// Canonical display label for a database engine (e.g. `postgres`,
|
|
/// `sqlserver`, `mongodb`) — the same identifier already used throughout
|
|
/// this module's own warning prose. The documentation collector uses it for
|
|
/// `database_type` and its engine-capability warnings instead of the Rust
|
|
/// `Debug` spelling (`Postgres`, `SqlServer`, `MongoDb`), which is an
|
|
/// implementation detail, not something a consumer like dbdocs/dbdiagram
|
|
/// should key off.
|
|
pub fn database_type_label(database_type: crate::models::connection::DatabaseType) -> String {
|
|
dialect::database_label(Some(database_type))
|
|
}
|
|
|
|
pub use indexes::has_existing_index_change;
|
|
pub use util::{clean, normalize_default, original_comment, original_default};
|