Skip to content

Commit 992a943

Browse files
authored
Merge pull request #32 from dev-five-git/idx-issue
Idx issue
2 parents 1627394 + 8e2f1e7 commit 992a943

File tree

174 files changed

+4437
-3473
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+4437
-3473
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes":{"crates/vespertide-planner/Cargo.toml":"Patch","crates/vespertide-query/Cargo.toml":"Patch","crates/vespertide/Cargo.toml":"Patch","crates/vespertide-core/Cargo.toml":"Patch","crates/vespertide-exporter/Cargo.toml":"Patch","crates/vespertide-config/Cargo.toml":"Patch","crates/vespertide-loader/Cargo.toml":"Patch","crates/vespertide-macro/Cargo.toml":"Patch","crates/vespertide-cli/Cargo.toml":"Patch","crates/vespertide-naming/Cargo.toml":"Patch"},"note":"Fix index, unique naming issue","date":"2025-12-19T06:56:36.275571Z"}

Cargo.lock

Lines changed: 17 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ vespertide-core = { path = "crates/vespertide-core", version = "0.1.14" }
1414
vespertide-config = { path = "crates/vespertide-config", version = "0.1.14" }
1515
vespertide-loader = { path = "crates/vespertide-loader", version = "0.1.14" }
1616
vespertide-macro = { path = "crates/vespertide-macro", version = "0.1.14" }
17+
vespertide-naming = { path = "crates/vespertide-naming", version = "0.1.14" }
1718
vespertide-planner = { path = "crates/vespertide-planner", version = "0.1.14" }
1819
vespertide-query = { path = "crates/vespertide-query", version = "0.1.14" }
1920
vespertide-exporter = { path = "crates/vespertide-exporter", version = "0.1.14" }

crates/vespertide-cli/src/commands/diff.rs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,6 @@ fn format_action(action: &MigrationAction) -> String {
8989
column.bright_cyan().bold()
9090
)
9191
}
92-
MigrationAction::AddIndex { table, index } => {
93-
format!(
94-
"{} {} {} {}",
95-
"Add index:".bright_green(),
96-
index.name.bright_cyan().bold(),
97-
"on".bright_white(),
98-
table.bright_cyan()
99-
)
100-
}
101-
MigrationAction::RemoveIndex { table, name } => {
102-
format!(
103-
"{} {} {} {}",
104-
"Remove index:".bright_red(),
105-
name.bright_cyan().bold(),
106-
"from".bright_white(),
107-
table.bright_cyan()
108-
)
109-
}
11092
MigrationAction::RenameTable { from, to } => {
11193
format!(
11294
"{} {} {} {}",
@@ -171,6 +153,13 @@ fn format_constraint_type(constraint: &vespertide_core::TableConstraint) -> Stri
171153
vespertide_core::TableConstraint::Check { name, expr } => {
172154
format!("{} CHECK ({})", name, expr)
173155
}
156+
vespertide_core::TableConstraint::Index { name, columns } => {
157+
if let Some(n) = name {
158+
format!("{} INDEX ({})", n, columns.join(", "))
159+
} else {
160+
format!("INDEX ({})", columns.join(", "))
161+
}
162+
}
174163
}
175164
}
176165

@@ -230,7 +219,6 @@ mod tests {
230219
auto_increment: false,
231220
columns: vec!["id".into()],
232221
}],
233-
indexes: vec![],
234222
};
235223
let path = models_dir.join(format!("{name}.json"));
236224
fs::write(path, serde_json::to_string_pretty(&table).unwrap()).unwrap();
@@ -284,19 +272,24 @@ mod tests {
284272
format!("{} {}.{}", "Modify column type:".bright_yellow(), "users".bright_cyan(), "id".bright_cyan().bold())
285273
)]
286274
#[case(
287-
MigrationAction::AddIndex {
275+
MigrationAction::AddConstraint {
288276
table: "users".into(),
289-
index: vespertide_core::IndexDef {
290-
name: "idx".into(),
277+
constraint: vespertide_core::TableConstraint::Index {
278+
name: Some("idx".into()),
291279
columns: vec!["id".into()],
292-
unique: false,
293280
},
294281
},
295-
format!("{} {} {} {}", "Add index:".bright_green(), "idx".bright_cyan().bold(), "on".bright_white(), "users".bright_cyan())
282+
format!("{} {} {} {}", "Add constraint:".bright_green(), "idx INDEX (id)".bright_cyan().bold(), "on".bright_white(), "users".bright_cyan())
296283
)]
297284
#[case(
298-
MigrationAction::RemoveIndex { table: "users".into(), name: "idx".into() },
299-
format!("{} {} {} {}", "Remove index:".bright_red(), "idx".bright_cyan().bold(), "from".bright_white(), "users".bright_cyan())
285+
MigrationAction::RemoveConstraint {
286+
table: "users".into(),
287+
constraint: vespertide_core::TableConstraint::Index {
288+
name: Some("idx".into()),
289+
columns: vec!["id".into()],
290+
},
291+
},
292+
format!("{} {} {} {}", "Remove constraint:".bright_red(), "idx INDEX (id)".bright_cyan().bold(), "from".bright_white(), "users".bright_cyan())
300293
)]
301294
#[case(
302295
MigrationAction::RenameTable { from: "users".into(), to: "accounts".into() },
@@ -433,4 +426,24 @@ mod tests {
433426
let result = cmd_diff();
434427
assert!(result.is_ok());
435428
}
429+
430+
#[test]
431+
fn test_constraint_display_unnamed_index() {
432+
let constraint = TableConstraint::Index {
433+
name: None,
434+
columns: vec!["email".into(), "username".into()],
435+
};
436+
let display = format_constraint_type(&constraint);
437+
assert_eq!(display, "INDEX (email, username)");
438+
}
439+
440+
#[test]
441+
fn test_constraint_display_named_index() {
442+
let constraint = TableConstraint::Index {
443+
name: Some("ix_users_email".into()),
444+
columns: vec!["email".into()],
445+
};
446+
let display = format_constraint_type(&constraint);
447+
assert_eq!(display, "ix_users_email INDEX (email)");
448+
}
436449
}

crates/vespertide-cli/src/commands/export.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,6 @@ mod tests {
261261
auto_increment: false,
262262
columns: vec!["id".into()],
263263
}],
264-
indexes: vec![],
265264
}
266265
}
267266

crates/vespertide-cli/src/commands/log.rs

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -58,36 +58,38 @@ pub fn cmd_log(backend: DatabaseBackend) -> Result<()> {
5858
}
5959

6060
for (i, pq) in plan_queries.iter().enumerate() {
61+
let queries = match backend {
62+
DatabaseBackend::Postgres => &pq.postgres,
63+
DatabaseBackend::MySql => &pq.mysql,
64+
DatabaseBackend::Sqlite => &pq.sqlite,
65+
};
66+
67+
// Build non-empty SQL statements
68+
let sql_statements: Vec<String> = queries
69+
.iter()
70+
.map(|q| q.build(backend).trim().to_string())
71+
.filter(|sql| !sql.is_empty())
72+
.collect();
73+
74+
// Print action description
6175
println!(
6276
" {}. {}",
6377
(i + 1).to_string().bright_magenta().bold(),
64-
match backend {
65-
DatabaseBackend::Postgres => pq
66-
.postgres
67-
.iter()
68-
.map(|q| q.build(DatabaseBackend::Postgres))
69-
.collect::<Vec<_>>()
70-
.join(";\n")
71-
.trim()
72-
.bright_white(),
73-
DatabaseBackend::MySql => pq
74-
.mysql
75-
.iter()
76-
.map(|q| q.build(DatabaseBackend::MySql))
77-
.collect::<Vec<_>>()
78-
.join(";\n")
79-
.trim()
80-
.bright_white(),
81-
DatabaseBackend::Sqlite => pq
82-
.sqlite
83-
.iter()
84-
.map(|q| q.build(DatabaseBackend::Sqlite))
85-
.collect::<Vec<_>>()
86-
.join(";\n")
87-
.trim()
88-
.bright_white(),
89-
}
78+
pq.action.to_string().bright_cyan()
9079
);
80+
81+
// Print SQL statements with sub-numbering if multiple
82+
for (j, sql) in sql_statements.iter().enumerate() {
83+
let prefix = if sql_statements.len() > 1 {
84+
format!(" {}-{}.", i + 1, j + 1)
85+
.bright_magenta()
86+
.bold()
87+
.to_string()
88+
} else {
89+
" ".to_string()
90+
};
91+
println!("{} {}", prefix, sql.bright_white());
92+
}
9193
}
9294

9395
println!();
@@ -226,4 +228,54 @@ mod tests {
226228
let result = cmd_log(DatabaseBackend::Sqlite);
227229
assert!(result.is_ok());
228230
}
231+
232+
#[test]
233+
#[serial_test::serial]
234+
fn cmd_log_with_multiple_sql_statements() {
235+
use vespertide_core::schema::primary_key::PrimaryKeySyntax;
236+
use vespertide_core::{ColumnDef, ColumnType, SimpleColumnType};
237+
238+
let tmp = tempdir().unwrap();
239+
let _guard = CwdGuard::new(&tmp.path().to_path_buf());
240+
241+
let cfg = VespertideConfig::default();
242+
write_config(&cfg);
243+
fs::create_dir_all(cfg.migrations_dir()).unwrap();
244+
245+
// Create a migration with ModifyColumnType for SQLite, which generates multiple SQL statements
246+
let plan = MigrationPlan {
247+
comment: Some("modify column type".into()),
248+
created_at: Some("2024-01-01T00:00:00Z".into()),
249+
version: 1,
250+
actions: vec![
251+
MigrationAction::CreateTable {
252+
table: "users".into(),
253+
columns: vec![ColumnDef {
254+
name: "id".into(),
255+
r#type: ColumnType::Simple(SimpleColumnType::Integer),
256+
nullable: false,
257+
default: None,
258+
comment: None,
259+
primary_key: Some(PrimaryKeySyntax::Bool(true)),
260+
unique: None,
261+
index: None,
262+
foreign_key: None,
263+
}],
264+
constraints: vec![],
265+
},
266+
MigrationAction::ModifyColumnType {
267+
table: "users".into(),
268+
column: "id".into(),
269+
new_type: ColumnType::Simple(SimpleColumnType::BigInt),
270+
},
271+
],
272+
};
273+
let path = cfg.migrations_dir().join("0001_modify_column_type.json");
274+
fs::write(path, serde_json::to_string_pretty(&plan).unwrap()).unwrap();
275+
276+
// SQLite backend will generate multiple SQL statements for ModifyColumnType (table recreation)
277+
// This exercises line 84 where sql_statements.len() > 1
278+
let result = cmd_log(DatabaseBackend::Sqlite);
279+
assert!(result.is_ok());
280+
}
229281
}

crates/vespertide-cli/src/commands/new.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ pub fn cmd_new(name: String, format: Option<FileFormat>) -> Result<()> {
3232
name: name.clone(),
3333
columns: Vec::new(),
3434
constraints: Vec::new(),
35-
indexes: Vec::new(),
3635
};
3736

3837
match format {

crates/vespertide-cli/src/commands/revision.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ mod tests {
178178
auto_increment: false,
179179
columns: vec!["id".into()],
180180
}],
181-
indexes: vec![],
182181
};
183182
let path = models_dir.join(format!("{name}.json"));
184183
fs::write(path, serde_json::to_string_pretty(&table).unwrap()).unwrap();

crates/vespertide-cli/src/commands/sql.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ mod tests {
163163
auto_increment: false,
164164
columns: vec!["id".into()],
165165
}],
166-
indexes: vec![],
167166
};
168167
let path = models_dir.join(format!("{name}.json"));
169168
fs::write(path, serde_json::to_string_pretty(&table).unwrap()).unwrap();
@@ -399,12 +398,11 @@ mod tests {
399398
}],
400399
constraints: vec![],
401400
},
402-
MigrationAction::AddIndex {
401+
MigrationAction::AddConstraint {
403402
table: "users".into(),
404-
index: vespertide_core::IndexDef {
405-
name: "idx_id".into(),
403+
constraint: TableConstraint::Index {
404+
name: Some("idx_id".into()),
406405
columns: vec!["id".into()],
407-
unique: false,
408406
},
409407
},
410408
],
@@ -463,7 +461,6 @@ mod tests {
463461
auto_increment: false,
464462
columns: vec!["id".into()],
465463
}],
466-
indexes: vec![],
467464
}];
468465

469466
let result = emit_sql(&plan, DatabaseBackend::Sqlite, &current_schema);

0 commit comments

Comments
 (0)