ignore column order

This commit is contained in:
Dull Bananas 2024-05-18 22:38:45 +00:00
parent d18c2c9cf3
commit 314e744594

View file

@ -1,5 +1,6 @@
use lemmy_utils::settings::SETTINGS; use lemmy_utils::settings::SETTINGS;
use std::{ use std::{
borrow::Cow,
collections::BTreeSet, collections::BTreeSet,
fmt::Write, fmt::Write,
process::{Command, Stdio}, process::{Command, Stdio},
@ -7,6 +8,7 @@ use std::{
pub fn get_dump() -> String { pub fn get_dump() -> String {
let output = Command::new("pg_dump") let output = Command::new("pg_dump")
.args(["--schema-only"])
.env("DATABASE_URL", SETTINGS.get_database_url()) .env("DATABASE_URL", SETTINGS.get_database_url())
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.output() .output()
@ -70,9 +72,9 @@ pub fn check_dump_diff(mut before: String, name: &str) {
] ]
.map(|chunks| { .map(|chunks| {
chunks chunks
.map(|&chunk| { .map(|chunk| {
( (
chunk, &**chunk,
// Used for ignoring formatting differences, especially indentation level, when // Used for ignoring formatting differences, especially indentation level, when
// determining which item in `only_in_before` corresponds to which item in `only_in_after` // determining which item in `only_in_before` corresponds to which item in `only_in_after`
chunk.replace([' ', '\t', '\r', '\n'], ""), chunk.replace([' ', '\t', '\r', '\n'], ""),
@ -104,7 +106,7 @@ pub fn check_dump_diff(mut before: String, name: &str) {
.expect("resize should have prevented this from failing"); .expect("resize should have prevented this from failing");
output.push('\n'); output.push('\n');
for line in diff::lines(most_similar_chunk, before_chunk) { for line in diff::lines(most_similar_chunk, &before_chunk) {
match line { match line {
diff::Result::Left(s) => write!(&mut output, "\n- {s}"), diff::Result::Left(s) => write!(&mut output, "\n- {s}"),
diff::Result::Right(s) => write!(&mut output, "\n+ {s}"), diff::Result::Right(s) => write!(&mut output, "\n+ {s}"),
@ -120,7 +122,7 @@ pub fn check_dump_diff(mut before: String, name: &str) {
} }
// todo inline? // todo inline?
fn chunks(dump: &str) -> impl Iterator<Item = &str> { fn chunks<'a>(dump: &'a str) -> impl Iterator<Item = Cow<'a, str>> {
let mut remaining = dump; let mut remaining = dump;
std::iter::from_fn(move || { std::iter::from_fn(move || {
remaining = remaining.trim_start(); remaining = remaining.trim_start();
@ -128,9 +130,24 @@ fn chunks(dump: &str) -> impl Iterator<Item = &str> {
remaining = remaining.split_once('\n')?.1; remaining = remaining.split_once('\n')?.1;
remaining = remaining.trim_start(); remaining = remaining.trim_start();
} }
let (a, b) = remaining.split_once("\n\n")?;
remaining = b;
// `a` can't be empty because of trim_start // `a` can't be empty because of trim_start
Some(a) let (result, after_result) = remaining.split_once("\n\n")?;
remaining = after_result;
Some(if result.starts_with("CREATE TABLE ") {
// Allow column order to change
let mut lines = result.lines().map(|line| line.strip_suffix(',').unwrap_or(line)).collect::<Vec<_>>();
lines.sort_unstable_by_key(|line| -> (u8, &str) {
let placement = match line.chars().next() {
Some('C') => 0,
Some(' ') => 1,
Some(')') => 2,
_ => panic!("unrecognized part of `CREATE TABLE` statement: {line}"),
};
(placement, line)
});
Cow::Owned(lines.join("\n"))
} else {
Cow::Borrowed(result)
})
}) })
} }