Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1f0e4c0c0 |
No files matched your search
@@ -1,3 +0,0 @@
|
|||||||
-- Data fix only: the cleared instants were wrong and are re-resolved by the
|
|
||||||
-- drain, so there is nothing to restore.
|
|
||||||
SELECT 1;
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-- #160 follow-up. The first fix (2026-10-16 migration) cleared rows whose
|
|
||||||
-- legacy `date_taken_source` was 'filename'. But the true-instant drain
|
|
||||||
-- (#118) re-ran the resolver over rows with a correct legacy date (e.g. an
|
|
||||||
-- exiftool container date) and wrote only the new-contract triple, so
|
|
||||||
-- some rows carry a filename-derived implausible year in `date_utc` while
|
|
||||||
-- their legacy pair says 'exiftool'. On prod: three VID_<counter> videos
|
|
||||||
-- (years 2095, 2229, 8580) whose containers say 2016/2017.
|
|
||||||
--
|
|
||||||
-- Clear just the triple on any row whose true instant is outside
|
|
||||||
-- [1995-01-01, 2028-01-01) UTC. `date_utc IS NULL` puts it back in
|
|
||||||
-- `backfill_utc_dates`, which re-resolves it with the gated matcher; the
|
|
||||||
-- legacy pair is left alone (it's frozen for rollback, and here correct).
|
|
||||||
UPDATE image_exif
|
|
||||||
SET date_utc = NULL,
|
|
||||||
camera_offset_minutes = NULL,
|
|
||||||
date_taken_tz_source = NULL
|
|
||||||
WHERE date_utc < 788918400 OR date_utc >= 1830297600;
|
|
||||||
+8
-82
@@ -495,92 +495,18 @@ mod tests {
|
|||||||
assert_eq!(rels, vec!["Screenshot_2014-06-01-20-44-50.png"]);
|
assert_eq!(rels, vec!["Screenshot_2014-06-01-20-44-50.png"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A connection migrated up to (not including) the migration whose
|
|
||||||
/// name contains `name`, for seeding the state a data fix repairs.
|
|
||||||
fn conn_before_migration(name: &str) -> SqliteConnection {
|
|
||||||
let mut conn = SqliteConnection::establish(":memory:").expect("in-memory sqlite");
|
|
||||||
for m in conn.pending_migrations(DB_MIGRATIONS).expect("pending") {
|
|
||||||
if m.name().to_string().contains(name) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
conn.run_migration(&*m).expect("migration");
|
|
||||||
}
|
|
||||||
conn
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn migration_clears_implausible_true_instants_but_keeps_legacy_dates() {
|
|
||||||
// The prod shape the first fix missed: a correct exiftool legacy
|
|
||||||
// date, with a filename-derived 2229 instant written by the drain.
|
|
||||||
let mut conn = conn_before_migration("reresolve_implausible_utc_dates");
|
|
||||||
seed_row(
|
|
||||||
&mut conn,
|
|
||||||
1,
|
|
||||||
"VID_22290524_080551_818.mp4",
|
|
||||||
Some(1_500_069_534),
|
|
||||||
Some("exiftool"),
|
|
||||||
);
|
|
||||||
seed_row(&mut conn, 1, "beach.jpg", Some(1_500_069_534), Some("exif"));
|
|
||||||
let set_utc = |conn: &mut SqliteConnection, path: &str, utc: i64| {
|
|
||||||
diesel::update(image_exif::table.filter(image_exif::rel_path.eq(path)))
|
|
||||||
.set((
|
|
||||||
image_exif::date_utc.eq(utc),
|
|
||||||
image_exif::camera_offset_minutes.eq(-300),
|
|
||||||
image_exif::date_taken_tz_source.eq("assumed_server"),
|
|
||||||
))
|
|
||||||
.execute(conn)
|
|
||||||
.unwrap();
|
|
||||||
};
|
|
||||||
set_utc(&mut conn, "VID_22290524_080551_818.mp4", 8_185_669_551);
|
|
||||||
set_utc(&mut conn, "beach.jpg", 1_500_069_534);
|
|
||||||
|
|
||||||
conn.run_pending_migrations(DB_MIGRATIONS)
|
|
||||||
.expect("fix migration");
|
|
||||||
|
|
||||||
type Row = (
|
|
||||||
String,
|
|
||||||
Option<i64>,
|
|
||||||
Option<String>,
|
|
||||||
Option<i64>,
|
|
||||||
Option<i32>,
|
|
||||||
);
|
|
||||||
let rows: Vec<Row> = image_exif::table
|
|
||||||
.select((
|
|
||||||
image_exif::rel_path,
|
|
||||||
image_exif::date_taken,
|
|
||||||
image_exif::date_taken_source,
|
|
||||||
image_exif::date_utc,
|
|
||||||
image_exif::camera_offset_minutes,
|
|
||||||
))
|
|
||||||
.order(image_exif::rel_path)
|
|
||||||
.load(&mut conn)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
rows,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
"VID_22290524_080551_818.mp4".into(),
|
|
||||||
Some(1_500_069_534),
|
|
||||||
Some("exiftool".into()),
|
|
||||||
None,
|
|
||||||
None
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"beach.jpg".into(),
|
|
||||||
Some(1_500_069_534),
|
|
||||||
Some("exif".into()),
|
|
||||||
Some(1_500_069_534),
|
|
||||||
Some(-300)
|
|
||||||
),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn migration_clears_implausible_filename_dates_for_re_resolution() {
|
fn migration_clears_implausible_filename_dates_for_re_resolution() {
|
||||||
// Migrate up to just before the #160 data fix, seed rows as the
|
// Migrate up to just before the #160 data fix, seed rows as the
|
||||||
// old matcher left them, then apply it.
|
// old matcher left them, then apply it.
|
||||||
let mut conn = conn_before_migration("reresolve_implausible_filename_dates");
|
const FIX: &str = "reresolve_implausible_filename_dates";
|
||||||
|
let mut conn = SqliteConnection::establish(":memory:").expect("in-memory sqlite");
|
||||||
|
for m in conn.pending_migrations(DB_MIGRATIONS).expect("pending") {
|
||||||
|
if m.name().to_string().contains(FIX) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
conn.run_migration(&*m).expect("migration");
|
||||||
|
}
|
||||||
// 2229-05-24 08:05:51 and 1053-05-19 10:15:27 (wall-as-UTC), a
|
// 2229-05-24 08:05:51 and 1053-05-19 10:15:27 (wall-as-UTC), a
|
||||||
// real 2014 filename date, and an fs_time row that isn't ours to
|
// real 2014 filename date, and an fs_time row that isn't ours to
|
||||||
// touch even though its date is odd.
|
// touch even though its date is odd.
|
||||||
|
|||||||
Reference in new issue
Block a user