| 22 | namespace { |
| 23 | |
| 24 | void Vacuum(const char* path) { |
| 25 | LOG(INFO) << "Opening SQLite DB: " << path; |
| 26 | Sqlite* db; |
| 27 | TF_CHECK_OK(Sqlite::Open(path, SQLITE_OPEN_READWRITE, &db)); |
| 28 | core::ScopedUnref db_unref(db); |
| 29 | |
| 30 | // TODO(jart): Maybe defragment rowids on Tensors. |
| 31 | // TODO(jart): Maybe LIMIT deletes and incremental VACUUM. |
| 32 | |
| 33 | // clang-format off |
| 34 | |
| 35 | LOG(INFO) << "Deleting orphaned Experiments"; |
| 36 | db->PrepareOrDie(R"sql( |
| 37 | DELETE FROM |
| 38 | Experiments |
| 39 | WHERE |
| 40 | user_id IS NOT NULL |
| 41 | AND user_id NOT IN (SELECT user_id FROM Users) |
| 42 | )sql").StepAndResetOrDie(); |
| 43 | |
| 44 | LOG(INFO) << "Deleting orphaned Runs"; |
| 45 | db->PrepareOrDie(R"sql( |
| 46 | DELETE FROM |
| 47 | Runs |
| 48 | WHERE |
| 49 | experiment_id IS NOT NULL |
| 50 | AND experiment_id NOT IN (SELECT experiment_id FROM Experiments) |
| 51 | )sql").StepAndResetOrDie(); |
| 52 | |
| 53 | LOG(INFO) << "Deleting orphaned Tags"; |
| 54 | db->PrepareOrDie(R"sql( |
| 55 | DELETE FROM |
| 56 | Tags |
| 57 | WHERE |
| 58 | run_id IS NOT NULL |
| 59 | AND run_id NOT IN (SELECT run_id FROM Runs) |
| 60 | )sql").StepAndResetOrDie(); |
| 61 | |
| 62 | // TODO(jart): What should we do if plugins define non-tag tensor series? |
| 63 | LOG(INFO) << "Deleting orphaned Tensors"; |
| 64 | db->PrepareOrDie(R"sql( |
| 65 | DELETE FROM |
| 66 | Tensors |
| 67 | WHERE |
| 68 | series IS NOT NULL |
| 69 | AND series NOT IN (SELECT tag_id FROM Tags) |
| 70 | )sql").StepAndResetOrDie(); |
| 71 | |
| 72 | LOG(INFO) << "Deleting orphaned TensorStrings"; |
| 73 | db->PrepareOrDie(R"sql( |
| 74 | DELETE FROM |
| 75 | TensorStrings |
| 76 | WHERE |
| 77 | tensor_rowid NOT IN (SELECT rowid FROM Tensors) |
| 78 | )sql").StepAndResetOrDie(); |
| 79 | |
| 80 | LOG(INFO) << "Deleting orphaned Graphs"; |
| 81 | db->PrepareOrDie(R"sql( |
no test coverage detected