diff --git a/.changepacks/changepack_log_QfIyEI--ezqnzhvAC7E3G.json b/.changepacks/changepack_log_QfIyEI--ezqnzhvAC7E3G.json new file mode 100644 index 0000000..4daf933 --- /dev/null +++ b/.changepacks/changepack_log_QfIyEI--ezqnzhvAC7E3G.json @@ -0,0 +1 @@ +{"changes":{"crates/vespertide-loader/Cargo.toml":"Patch","crates/vespertide-planner/Cargo.toml":"Patch","crates/vespertide-core/Cargo.toml":"Patch","crates/vespertide-config/Cargo.toml":"Patch","crates/vespertide-macro/Cargo.toml":"Patch","crates/vespertide-naming/Cargo.toml":"Patch","crates/vespertide-query/Cargo.toml":"Patch","crates/vespertide-exporter/Cargo.toml":"Patch","crates/vespertide/Cargo.toml":"Patch","crates/vespertide-cli/Cargo.toml":"Patch"},"note":"Fix auto increament","date":"2025-12-26T09:47:05.639827500Z"} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 8bdf6b8..a7e7a6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2995,7 +2995,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vespertide" -version = "0.1.17" +version = "0.1.18" dependencies = [ "vespertide-core", "vespertide-macro", @@ -3003,7 +3003,7 @@ dependencies = [ [[package]] name = "vespertide-cli" -version = "0.1.17" +version = "0.1.18" dependencies = [ "anyhow", "assert_cmd", @@ -3028,7 +3028,7 @@ dependencies = [ [[package]] name = "vespertide-config" -version = "0.1.17" +version = "0.1.18" dependencies = [ "clap", "serde", @@ -3036,7 +3036,7 @@ dependencies = [ [[package]] name = "vespertide-core" -version = "0.1.17" +version = "0.1.18" dependencies = [ "rstest", "schemars", @@ -3047,7 +3047,7 @@ dependencies = [ [[package]] name = "vespertide-exporter" -version = "0.1.17" +version = "0.1.18" dependencies = [ "insta", "rstest", @@ -3057,7 +3057,7 @@ dependencies = [ [[package]] name = "vespertide-loader" -version = "0.1.17" +version = "0.1.18" dependencies = [ "anyhow", "rstest", @@ -3072,7 +3072,7 @@ dependencies = [ [[package]] name = "vespertide-macro" -version = "0.1.17" +version = "0.1.18" dependencies = [ "proc-macro2", "quote", @@ -3089,11 +3089,11 @@ dependencies = [ [[package]] name = "vespertide-naming" -version = "0.1.17" +version = "0.1.18" [[package]] name = "vespertide-planner" -version = "0.1.17" +version = "0.1.18" dependencies = [ "insta", "rstest", @@ -3104,7 +3104,7 @@ dependencies = [ [[package]] name = "vespertide-query" -version = "0.1.17" +version = "0.1.18" dependencies = [ "insta", "rstest", diff --git a/crates/vespertide-query/src/sql/create_table.rs b/crates/vespertide-query/src/sql/create_table.rs index 9d5fc14..b7dfc11 100644 --- a/crates/vespertide-query/src/sql/create_table.rs +++ b/crates/vespertide-query/src/sql/create_table.rs @@ -21,6 +21,23 @@ pub(crate) fn build_create_table_for_backend( .iter() .any(|c| matches!(c, TableConstraint::PrimaryKey { .. })); + // Extract auto_increment columns from constraints + let auto_increment_columns: std::collections::HashSet<&str> = constraints + .iter() + .filter_map(|c| { + if let TableConstraint::PrimaryKey { + columns: pk_cols, + auto_increment: true, + } = c + { + Some(pk_cols.iter().map(|s| s.as_str()).collect::>()) + } else { + None + } + }) + .flatten() + .collect(); + // Add columns for column in columns { let mut col = build_sea_column_def_with_table(backend, table, column); @@ -30,6 +47,11 @@ pub(crate) fn build_create_table_for_backend( col.primary_key(); } + // Apply auto_increment if this column is in the auto_increment primary key + if auto_increment_columns.contains(column.name.as_str()) { + col.auto_increment(); + } + // NOTE: We do NOT add inline unique constraints here. // All unique constraints are handled as separate CREATE UNIQUE INDEX statements // so they have proper names and can be dropped later. @@ -502,4 +524,126 @@ mod tests { assert_snapshot!(sql); }); } + + #[rstest] + #[case::auto_increment_postgres(DatabaseBackend::Postgres)] + #[case::auto_increment_mysql(DatabaseBackend::MySql)] + #[case::auto_increment_sqlite(DatabaseBackend::Sqlite)] + fn test_create_table_with_auto_increment_primary_key(#[case] backend: DatabaseBackend) { + // Test that auto_increment on primary key generates SERIAL/AUTO_INCREMENT/AUTOINCREMENT + let columns = vec![ColumnDef { + name: "id".into(), + r#type: ColumnType::Simple(SimpleColumnType::Integer), + nullable: false, + default: None, + comment: None, + primary_key: None, + unique: None, + index: None, + foreign_key: None, + }]; + let constraints = vec![TableConstraint::PrimaryKey { + auto_increment: true, + columns: vec!["id".into()], + }]; + + let result = build_create_table(&backend, "users", &columns, &constraints); + assert!(result.is_ok()); + let queries = result.unwrap(); + let sql = queries + .iter() + .map(|q| q.build(backend)) + .collect::>() + .join(";\n"); + + // Verify auto_increment is applied correctly for each backend + match backend { + DatabaseBackend::Postgres => { + assert!( + sql.contains("SERIAL") || sql.contains("serial"), + "PostgreSQL should use SERIAL for auto_increment, got: {}", + sql + ); + } + DatabaseBackend::MySql => { + assert!( + sql.contains("AUTO_INCREMENT") || sql.contains("auto_increment"), + "MySQL should use AUTO_INCREMENT for auto_increment, got: {}", + sql + ); + } + DatabaseBackend::Sqlite => { + assert!( + sql.contains("AUTOINCREMENT") || sql.contains("autoincrement"), + "SQLite should use AUTOINCREMENT for auto_increment, got: {}", + sql + ); + } + } + + with_settings!({ snapshot_suffix => format!("create_table_with_auto_increment_{:?}", backend) }, { + assert_snapshot!(sql); + }); + } + + #[rstest] + #[case::inline_auto_increment_postgres(DatabaseBackend::Postgres)] + #[case::inline_auto_increment_mysql(DatabaseBackend::MySql)] + #[case::inline_auto_increment_sqlite(DatabaseBackend::Sqlite)] + fn test_create_table_with_inline_auto_increment_primary_key(#[case] backend: DatabaseBackend) { + // Test that inline primary_key with auto_increment generates correct SQL + use vespertide_core::schema::primary_key::{PrimaryKeyDef, PrimaryKeySyntax}; + + let columns = vec![ColumnDef { + name: "id".into(), + r#type: ColumnType::Simple(SimpleColumnType::Integer), + nullable: false, + default: None, + comment: None, + primary_key: Some(PrimaryKeySyntax::Object(PrimaryKeyDef { + auto_increment: true, + })), + unique: None, + index: None, + foreign_key: None, + }]; + + let result = build_create_table(&backend, "users", &columns, &[]); + assert!(result.is_ok()); + let queries = result.unwrap(); + let sql = queries + .iter() + .map(|q| q.build(backend)) + .collect::>() + .join(";\n"); + + // Verify auto_increment is applied correctly for each backend + match backend { + DatabaseBackend::Postgres => { + assert!( + sql.contains("SERIAL") || sql.contains("serial"), + "PostgreSQL should use SERIAL for auto_increment, got: {}", + sql + ); + } + DatabaseBackend::MySql => { + assert!( + sql.contains("AUTO_INCREMENT") || sql.contains("auto_increment"), + "MySQL should use AUTO_INCREMENT for auto_increment, got: {}", + sql + ); + } + DatabaseBackend::Sqlite => { + assert!( + sql.contains("AUTOINCREMENT") || sql.contains("autoincrement"), + "SQLite should use AUTOINCREMENT for auto_increment, got: {}", + sql + ); + } + } + + with_settings!({ snapshot_suffix => format!("create_table_with_inline_auto_increment_{:?}", backend) }, { + assert_snapshot!(sql); + }); + } } diff --git a/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_MySql.snap b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_MySql.snap new file mode 100644 index 0000000..9ffbd20 --- /dev/null +++ b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_MySql.snap @@ -0,0 +1,5 @@ +--- +source: crates/vespertide-query/src/sql/create_table.rs +expression: sql +--- +CREATE TABLE `users` ( `id` int NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) diff --git a/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_Postgres.snap b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_Postgres.snap new file mode 100644 index 0000000..220dc94 --- /dev/null +++ b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_Postgres.snap @@ -0,0 +1,5 @@ +--- +source: crates/vespertide-query/src/sql/create_table.rs +expression: sql +--- +CREATE TABLE "users" ( "id" serial NOT NULL, PRIMARY KEY ("id") ) diff --git a/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_Sqlite.snap b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_Sqlite.snap new file mode 100644 index 0000000..43c926a --- /dev/null +++ b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_auto_increment_primary_key@create_table_with_auto_increment_Sqlite.snap @@ -0,0 +1,5 @@ +--- +source: crates/vespertide-query/src/sql/create_table.rs +expression: sql +--- +CREATE TABLE "users" ( "id" integer NOT NULL AUTOINCREMENT, PRIMARY KEY ("id") ) diff --git a/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_MySql.snap b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_MySql.snap new file mode 100644 index 0000000..9ffbd20 --- /dev/null +++ b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_MySql.snap @@ -0,0 +1,5 @@ +--- +source: crates/vespertide-query/src/sql/create_table.rs +expression: sql +--- +CREATE TABLE `users` ( `id` int NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) diff --git a/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_Postgres.snap b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_Postgres.snap new file mode 100644 index 0000000..220dc94 --- /dev/null +++ b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_Postgres.snap @@ -0,0 +1,5 @@ +--- +source: crates/vespertide-query/src/sql/create_table.rs +expression: sql +--- +CREATE TABLE "users" ( "id" serial NOT NULL, PRIMARY KEY ("id") ) diff --git a/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_Sqlite.snap b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_Sqlite.snap new file mode 100644 index 0000000..43c926a --- /dev/null +++ b/crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__create_table__tests__create_table_with_inline_auto_increment_primary_key@create_table_with_inline_auto_increment_Sqlite.snap @@ -0,0 +1,5 @@ +--- +source: crates/vespertide-query/src/sql/create_table.rs +expression: sql +--- +CREATE TABLE "users" ( "id" integer NOT NULL AUTOINCREMENT, PRIMARY KEY ("id") )