diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb index e1916cb563..470fcbf488 100644 --- a/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record.rb @@ -4,6 +4,7 @@ require_relative "active_record/generators/rails_migration_generator" require_relative "active_record/generators/templates/template_directory" require_relative "active_record/generators/verify_data_type_for_adapter" +require_relative "active_record/generators/event_id_index_migration_generator" require_relative "active_record/event" require_relative "active_record/with_default_models" require_relative "active_record/with_abstract_base_class" diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/generators/event_id_index_migration_generator.rb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/generators/event_id_index_migration_generator.rb new file mode 100644 index 0000000000..8c1e2bc807 --- /dev/null +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/generators/event_id_index_migration_generator.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module RubyEventStore + module ActiveRecord + class EventIdIndexMigrationGenerator + def call(migration_path) + path = build_path(migration_path) + write_to_file(path) + path + end + + private + + def absolute_path(path) + File.expand_path(path, __dir__) + end + + def migration_code + migration_template.result_with_hash(migration_version: migration_version) + end + + def migration_template + ERB.new( + File.read( + File.join(absolute_path("./templates"), "add_event_id_index_to_event_store_events_in_streams_template.erb") + ) + ) + end + + def migration_version + ::ActiveRecord::Migration.current_version + end + + def timestamp + Time.now.strftime("%Y%m%d%H%M%S") + end + + def write_to_file(path) + File.write(path, migration_code) + end + + def build_path(migration_path) + File.join("#{migration_path}", "#{timestamp}_add_event_id_index_to_event_store_events_in_streams.rb") + end + end + end +end diff --git a/ruby_event_store-active_record/lib/ruby_event_store/active_record/generators/templates/add_event_id_index_to_event_store_events_in_streams_template.erb b/ruby_event_store-active_record/lib/ruby_event_store/active_record/generators/templates/add_event_id_index_to_event_store_events_in_streams_template.erb new file mode 100644 index 0000000000..6b96e4e44e --- /dev/null +++ b/ruby_event_store-active_record/lib/ruby_event_store/active_record/generators/templates/add_event_id_index_to_event_store_events_in_streams_template.erb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddEventIdIndexToEventStoreEventsInStreams < ActiveRecord::Migration[<%= migration_version %>] + def change + return if index_exists?(:event_store_events_in_streams, :event_id) + + add_index :event_store_events_in_streams, [:event_id] + end +end diff --git a/ruby_event_store-active_record/spec/event_id_index_migration_generator_spec.rb b/ruby_event_store-active_record/spec/event_id_index_migration_generator_spec.rb new file mode 100644 index 0000000000..5dbf392e8c --- /dev/null +++ b/ruby_event_store-active_record/spec/event_id_index_migration_generator_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require "spec_helper" +require_relative "../../support/helpers/silence_stdout" + +module RubyEventStore + module ActiveRecord + ::RSpec.describe EventIdIndexMigrationGenerator do + around { |example| SilenceStdout.silence_stdout { example.run } } + around do |example| + begin + @dir = Dir.mktmpdir(nil, "./") + example.call + ensure + FileUtils.rm_r(@dir) + FileUtils.rm_f(["./20221130213700_add_event_id_index_to_event_store_events_in_streams.rb"]) + end + end + + before { allow(Time).to receive(:now).and_return(Time.new(2022, 11, 30, 21, 37, 00)) } + + specify "it is created within specified directory" do + migration_generator(@dir) + + expect(migration_exists?(@dir)).to be_truthy + end + + specify "returns path to migration file" do + path = migration_generator(@dir) + + expected_path = "#{@dir}/20221130213700_add_event_id_index_to_event_store_events_in_streams.rb" + expect(path).to match(expected_path) + end + + specify "uses particular migration version" do + migration_generator(@dir) + + expect(read_migration(@dir)).to include("ActiveRecord::Migration[#{::ActiveRecord::Migration.current_version}]") + end + + specify "uses particular migration version for rails 6.0" do + skip unless ENV["BUNDLE_GEMFILE"]&.include?("rails_6_0") + + migration_generator(@dir) + + expect(read_migration(@dir)).to include("ActiveRecord::Migration[6.0]") + end + + specify "uses particular migration version for rails 6.1" do + skip unless ENV["BUNDLE_GEMFILE"]&.include?("rails_6_1") + + migration_generator(@dir) + + expect(read_migration(@dir)).to include("ActiveRecord::Migration[6.1]") + end + + private + + def migration_generator(dir) + EventIdIndexMigrationGenerator.new.call(dir) + end + + def migration_exists?(dir) + File.exist?("#{dir}/20221130213700_add_event_id_index_to_event_store_events_in_streams.rb") + end + + def read_migration(dir) + File.read("#{dir}/20221130213700_add_event_id_index_to_event_store_events_in_streams.rb") + end + end + end +end diff --git a/ruby_event_store-active_record/spec/migration_test_spec.rb b/ruby_event_store-active_record/spec/migration_test_spec.rb index 63d448b802..6d40f52534 100644 --- a/ruby_event_store-active_record/spec/migration_test_spec.rb +++ b/ruby_event_store-active_record/spec/migration_test_spec.rb @@ -57,9 +57,9 @@ module ActiveRecord Indexes: "event_store_events_in_streams_pkey" PRIMARY KEY, btree (id) "index_event_store_events_in_streams_on_created_at" btree (created_at) + "index_event_store_events_in_streams_on_event_id" btree (event_id) "index_event_store_events_in_streams_on_stream_and_event_id" UNIQUE, btree (stream, event_id) "index_event_store_events_in_streams_on_stream_and_position" UNIQUE, btree (stream, "position") - "index_event_store_events_in_streams_on_event_id" btree (event_id) SCHEMA end @@ -101,8 +101,8 @@ module ActiveRecord PRIMARY KEY (`id`), UNIQUE KEY `index_event_store_events_in_streams_on_stream_and_event_id` (`stream`,`event_id`), UNIQUE KEY `index_event_store_events_in_streams_on_stream_and_position` (`stream`,`position`), - KEY `index_event_store_events_in_streams_on_event_id` (`event_id`), - KEY `index_event_store_events_in_streams_on_created_at` (`created_at`) + KEY `index_event_store_events_in_streams_on_created_at` (`created_at`), + KEY `index_event_store_events_in_streams_on_event_id` (`event_id`) ) ENGINE=InnoDB DEFAULT CHARSET=#{charset}#{collation} SCHEMA end