feat(ugc): read one model's makes with their options

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-30 21:27:56 -05:00
parent 1d7f047317
commit e728c71475
7 changed files with 40 additions and 0 deletions

View File

@@ -142,6 +142,13 @@ public:
};
virtual std::vector<RunSummary> GetUgcRunSummaries() = 0;
// One model's makes (ugc_process_runs), the newest first, at most `limit`
struct ModelRun {
int64_t madeAt{}; // unix seconds
ProcessRun run;
};
virtual std::vector<ModelRun> GetUgcModelRuns(const LWOOBJID id, const uint32_t limit) = 0;
virtual std::optional<ProcessInfo> GetUgcProcessInfo(const LWOOBJID id) = 0;
// Sets models back to pending with no attempts: one (`id`), or all of them (`id` nullopt; only the failed ones

View File

@@ -482,6 +482,7 @@ public:
uint64_t ResetPropertyUgcModelProcessing(const LWOOBJID propertyId, const std::string_view options) override;
void RecordUgcModelRun(const ProcessRun& run) override;
std::vector<IUgc::RunSummary> GetUgcRunSummaries() override;
std::vector<IUgc::ModelRun> GetUgcModelRuns(const LWOOBJID id, const uint32_t limit) override;
IUgc::ProcessTotals GetUgcProcessTotals(const bool modular) override;
std::vector<IUgc::ProcessInfo> GetUgcProcessList(const std::optional<eProcessState> state, const std::string_view search, const uint32_t offset, const uint32_t limit) override;
std::vector<std::pair<IUgc::eProcessState, uint64_t>> GetUgcProcessCounts() override;

View File

@@ -192,6 +192,18 @@ std::vector<IUgc::RunSummary> MySQLDatabase::GetUgcRunSummaries() {
return summaries;
}
std::vector<IUgc::ModelRun> MySQLDatabase::GetUgcModelRuns(const LWOOBJID id, const uint32_t limit) {
auto result = ExecuteSelect("SELECT made_at, options, process_ms, process_cpu_ms, hsr_ms, ao_ms, icon_ms, bricks, triangles_before, triangles FROM ugc_process_runs "
"WHERE ugc_id = ? ORDER BY made_at DESC, id DESC LIMIT ?;", id, limit);
std::vector<ModelRun> runs;
while (result->next()) {
const auto field = [&](const char* name) { return static_cast<uint32_t>(result->getUInt(name)); };
runs.push_back({ result->getInt64("made_at"), { id, std::string(result->getString("options").c_str()), field("process_ms"), field("process_cpu_ms"),
field("hsr_ms"), field("ao_ms"), field("icon_ms"), field("bricks"), field("triangles_before"), field("triangles") } });
}
return runs;
}
std::vector<IUgc::ProcessInfo> MySQLDatabase::GetUgcProcessList(const std::optional<eProcessState> state, const std::string_view search, const uint32_t offset, const uint32_t limit) {
const std::string select =
"SELECT u.id, u.character_id, c.name AS character_name, u.is_optimized, u.process_attempts, u.processed_at, u.process_error, u.bake_ao, u.process_after "

View File

@@ -466,6 +466,7 @@ public:
uint64_t ResetPropertyUgcModelProcessing(const LWOOBJID propertyId, const std::string_view options) override;
void RecordUgcModelRun(const ProcessRun& run) override;
std::vector<IUgc::RunSummary> GetUgcRunSummaries() override;
std::vector<IUgc::ModelRun> GetUgcModelRuns(const LWOOBJID id, const uint32_t limit) override;
IUgc::ProcessTotals GetUgcProcessTotals(const bool modular) override;
std::vector<IUgc::ProcessInfo> GetUgcProcessList(const std::optional<eProcessState> state, const std::string_view search, const uint32_t offset, const uint32_t limit) override;
std::vector<std::pair<IUgc::eProcessState, uint64_t>> GetUgcProcessCounts() override;

View File

@@ -194,6 +194,19 @@ std::vector<IUgc::RunSummary> SQLiteDatabase::GetUgcRunSummaries() {
return summaries;
}
std::vector<IUgc::ModelRun> SQLiteDatabase::GetUgcModelRuns(const LWOOBJID id, const uint32_t limit) {
auto [_, result] = ExecuteSelect("SELECT made_at, options, process_ms, process_cpu_ms, hsr_ms, ao_ms, icon_ms, bricks, triangles_before, triangles FROM ugc_process_runs "
"WHERE ugc_id = ? ORDER BY made_at DESC, id DESC LIMIT ?;", id, limit);
std::vector<ModelRun> runs;
while (!result.eof()) {
const auto field = [&](const char* name) { return static_cast<uint32_t>(result.getInt64Field(name, 0)); };
runs.push_back({ result.getInt64Field("made_at", 0), { id, result.getStringField("options", ""), field("process_ms"), field("process_cpu_ms"),
field("hsr_ms"), field("ao_ms"), field("icon_ms"), field("bricks"), field("triangles_before"), field("triangles") } });
result.nextRow();
}
return runs;
}
std::vector<IUgc::ProcessInfo> SQLiteDatabase::GetUgcProcessList(const std::optional<eProcessState> state, const std::string_view search, const uint32_t offset, const uint32_t limit) {
const std::string select =
"SELECT u.id, u.character_id, c.name AS character_name, u.is_optimized, u.process_attempts, u.processed_at, u.process_error, u.bake_ao, u.process_after "

View File

@@ -461,6 +461,7 @@ class TestSQLDatabase : public GameDatabase {
uint64_t ResetPropertyUgcModelProcessing(const LWOOBJID propertyId, const std::string_view options) override { return 0; }
void RecordUgcModelRun(const ProcessRun& run) override {}
std::vector<IUgc::RunSummary> GetUgcRunSummaries() override { return {}; }
std::vector<IUgc::ModelRun> GetUgcModelRuns(const LWOOBJID id, const uint32_t limit) override { return {}; }
IUgc::ProcessTotals GetUgcProcessTotals(const bool modular) override { return {}; }
std::vector<IUgc::ProcessInfo> GetUgcProcessList(const std::optional<eProcessState> state, const std::string_view search, const uint32_t offset, const uint32_t limit) override { return {}; }
std::vector<std::pair<IUgc::eProcessState, uint64_t>> GetUgcProcessCounts() override { return {}; }

View File

@@ -825,6 +825,11 @@ TEST_F(ParitySeeded, UgcModel) {
for (const auto& s : db.GetUgcRunSummaries()) {
out.push_back({ s.options, s.runs, s.models, s.milliseconds, s.cpuMilliseconds, s.hsrMilliseconds, s.aoMilliseconds, s.iconMilliseconds, s.bricks, s.trianglesBefore, s.triangles });
}
// One model's makes, the newest first, limited
for (const auto& [madeAt, r] : db.GetUgcModelRuns(1152921510000500001LL, 2)) {
out.push_back({ madeAt > 0, r.options, r.milliseconds, r.cpuMilliseconds, r.hsrMilliseconds, r.aoMilliseconds, r.iconMilliseconds, r.bricks, r.trianglesBefore, r.triangles });
}
out.push_back(db.GetUgcModelRuns(1152921510000500002LL, 10).size());
return out;
});
Both("Modular build processing", [&](GameDatabase& db) {