From b19c95187b5c473af4b6695a856574b587e96afd Mon Sep 17 00:00:00 2001 From: Gregory Ballantine Date: Thu, 11 Sep 2025 16:09:00 -0400 Subject: [PATCH] [Issue #16] - Abstracted benchmarks from tests via BenchmarkProfile model, to allow for linking benchmarks with different runtime settings --- .../0004_add_benchmarksettings_table.rb | 97 +++++++++++++++++++ src/controllers/index.rb | 1 + src/models/benchmark.rb | 3 +- src/models/benchmark_profile.rb | 14 +++ src/models/result.rb | 2 +- src/models/test.rb | 4 +- views/benchmark/view.erb | 20 ++-- views/index/index.erb | 2 +- 8 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 db/migrations/0004_add_benchmarksettings_table.rb create mode 100644 src/models/benchmark_profile.rb diff --git a/db/migrations/0004_add_benchmarksettings_table.rb b/db/migrations/0004_add_benchmarksettings_table.rb new file mode 100644 index 0000000..6219ece --- /dev/null +++ b/db/migrations/0004_add_benchmarksettings_table.rb @@ -0,0 +1,97 @@ +Sequel.migration do + up do + # 1. Create benchmark_profiles + create_table(:benchmark_profiles) do + primary_key :id + String :label, null: false + String :settings, null: false + foreign_key :benchmark_id, :benchmarks, null: false, on_delete: :cascade + DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP + DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP + end + + # 2. Create join table (tests <-> benchmark_profiles) + create_table(:benchmark_profiles_tests) do + primary_key :id + foreign_key :test_id, :tests, null: false, on_delete: :cascade + foreign_key :benchmark_profile_id, :benchmark_profiles, null: false, on_delete: :cascade + + index [:test_id, :benchmark_profile_id], unique: true + end + + # 3. Add benchmark_profile_id to results + alter_table(:results) do + add_foreign_key :benchmark_profile_id, :benchmark_profiles, null: true, on_delete: :cascade + end + + # 4. Migrate data from old schema + from(:benchmarks).each do |b_row| + # Create a BenchmarkProfile for this (test, benchmark) pair + bp_id = self[:benchmark_profiles].insert( + benchmark_id: b_row[:id], + label: 'Default', + settings: '{}' + ) + + from(:benchmarks_tests).each do |bt_row| + if bt_row[:benchmark_id] == b_row[:id] + # Link it to the test + self[:benchmark_profiles_tests].insert( + test_id: bt_row[:test_id], + benchmark_profile_id: bp_id + ) + + # Update results belonging to this test + benchmark pair + self[:results] + .where(test_id: bt_row[:test_id], benchmark_id: bt_row[:benchmark_id]) + .update(benchmark_profile_id: bp_id) + end + end + end + + # 5. Clean up old schema + alter_table(:results) do + drop_foreign_key :benchmark_id + end + + drop_table(:benchmarks_tests) + end + + down do + # 1. Recreate old join table + create_table(:benchmarks_tests) do + foreign_key :test_id, :tests, null: false + foreign_key :benchmark_id, :benchmarks, null: false + end + + # 2. Add benchmark_id back to results + alter_table(:results) do + add_foreign_key :benchmark_id, :benchmarks, null: true + end + + # 3. Restore data + from(:benchmark_profiles_tests).each do |bpt_row| + bp = self[:benchmark_profiles][id: bpt_row[:benchmark_profile_id]] + next unless bp # safety check + + # Recreate old benchmarks_tests entry + self[:benchmarks_tests].insert( + test_id: bpt_row[:test_id], + benchmark_id: bp[:benchmark_id] + ) + + # Update results to point back to benchmark_id + self[:results] + .where(test_id: bpt_row[:test_id], benchmark_profile_id: bp[:id]) + .update(benchmark_id: bp[:benchmark_id]) + end + + # 4. Remove new schema + alter_table(:results) do + drop_foreign_key :benchmark_profile_id + end + + drop_table(:benchmark_profiles_tests) + drop_table(:benchmark_profiles) + end +end diff --git a/src/controllers/index.rb b/src/controllers/index.rb index 15cd3af..c0c109a 100644 --- a/src/controllers/index.rb +++ b/src/controllers/index.rb @@ -2,6 +2,7 @@ require_relative 'base_controller' require_relative '../models/test' +require_relative '../models/benchmark_profile' # / (top-level) routes class IndexController < BaseController diff --git a/src/models/benchmark.rb b/src/models/benchmark.rb index 875cbbb..eb46d13 100644 --- a/src/models/benchmark.rb +++ b/src/models/benchmark.rb @@ -3,7 +3,6 @@ # Benchmark - database model for PC benchmarks class Benchmark < Sequel::Model - many_to_many :tests - one_to_many :results + one_to_many :benchmark_profiles end diff --git a/src/models/benchmark_profile.rb b/src/models/benchmark_profile.rb new file mode 100644 index 0000000..96bf0a3 --- /dev/null +++ b/src/models/benchmark_profile.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# BenchmarkProfile - database model for benchmark settings profile +class BenchmarkProfile < Sequel::Model + + many_to_one :benchmark + many_to_many :tests + one_to_many :results + + def display_name + "#{benchmark.name} @ #{label}" + end + +end diff --git a/src/models/result.rb b/src/models/result.rb index 4b7e23a..16f3d76 100644 --- a/src/models/result.rb +++ b/src/models/result.rb @@ -4,7 +4,7 @@ class Result < Sequel::Model many_to_one :test - many_to_one :benchmark + many_to_one :benchmark_profile def formatted_score return @avg_score diff --git a/src/models/test.rb b/src/models/test.rb index 8022cd6..6a6ac85 100644 --- a/src/models/test.rb +++ b/src/models/test.rb @@ -5,10 +5,10 @@ class Test < Sequel::Model one_to_many :result many_to_one :hardware - many_to_many :benchmarks + many_to_many :benchmark_profiles def benchmark?(benchmark_id) - return benchmarks_dataset.where(Sequel[:benchmarks][:id] => benchmark_id).any? + return benchmark_profiles_dataset.where(Sequel[:benchmark][:id] => benchmark_id).any? end end diff --git a/views/benchmark/view.erb b/views/benchmark/view.erb index fe595ca..7f56c5c 100644 --- a/views/benchmark/view.erb +++ b/views/benchmark/view.erb @@ -21,29 +21,31 @@
-

Tests using this benchmark:

+

Profiles created for this benchmark:

- <% if benchmark.tests.length > 0 %> + <% if benchmark.benchmark_profiles.length > 0 %> - - + + + - <% benchmark.tests.each do |t| %> + <% benchmark.benchmark_profiles.each do |bp| %> - - - + + + + <% end %>
Test titleBenchmarksProfile LabelTests LinkedCreated at Last updated
<%= t.name %><%= t.benchmarks.length %><%= t.updated_at %><%= bp.display_name %><%= bp.tests.length %><%= bp.created_at %><%= bp.updated_at %>
<% else %> -

There are no tests associated with this benchmark.

+

There are no profiles associated with this benchmark.

<% end %>
diff --git a/views/index/index.erb b/views/index/index.erb index 080fae2..e11b3a1 100644 --- a/views/index/index.erb +++ b/views/index/index.erb @@ -17,7 +17,7 @@ <% tests.each do |t| %> <%= t.name %> - <%= t.benchmarks.length %> + <%= t.benchmark_profiles.length %> <%= t.updated_at %> <% end %>