Skip to content

Commit

Permalink
Try multi-db support
Browse files Browse the repository at this point in the history
This is mostly replacing `ActiveRecord::Base` with the actual model, so
that we connect to the right database.
  • Loading branch information
ameykusurkar committed Nov 22, 2023
1 parent 9a4e17d commit 9941f41
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions lib/statesman/adapters/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module Adapters
class ActiveRecord
JSON_COLUMN_TYPES = %w[json jsonb].freeze

# TODO: this should really take `connection` as an argument
def self.database_supports_partial_indexes?
# Rails 3 doesn't implement `supports_partial_index?`
if ::ActiveRecord::Base.connection.respond_to?(:supports_partial_index?)
Expand All @@ -16,6 +17,9 @@ def self.database_supports_partial_indexes?
end
end

# TODO: this used in Statesman::Config to determine if it is a MySQL database
# so that it can set some specific config. Feels like the right thing to do is
# for users to initialise the config per-database.
def self.adapter_name
::ActiveRecord::Base.connection.adapter_name.downcase
end
Expand All @@ -29,6 +33,7 @@ def initialize(transition_class, parent_model, observer, options = {})
raise IncompatibleSerializationError, transition_class.name
end

# TODO: We should probably check `@transition_class.is_a?(::ActiveRecord::Base)`
@transition_class = transition_class
@transition_table = transition_class.arel_table
@parent_model = parent_model
Expand Down Expand Up @@ -88,7 +93,7 @@ def create_transition(from, to, metadata)
default_transition_attributes(to, metadata),
)

::ActiveRecord::Base.transaction(requires_new: true) do
@transition_class.transaction(requires_new: true) do
@observer.execute(:before, from, to, transition)

if mysql_gaplock_protection?
Expand Down Expand Up @@ -130,8 +135,8 @@ def default_transition_attributes(to, metadata)
end

def add_after_commit_callback(from, to, transition)
::ActiveRecord::Base.connection.add_transaction_record(
ActiveRecordAfterCommitWrap.new do
@transition_class.connection.add_transaction_record(
ActiveRecordAfterCommitWrap.new(@transition_class.connection) do
@observer.execute(:after_commit, from, to, transition)
end,
)
Expand All @@ -154,7 +159,7 @@ def update_most_recents(most_recent_id = nil)
# most_recent before setting the new row to be true.
update.order(transition_table[:most_recent].desc) if mysql_gaplock_protection?

::ActiveRecord::Base.connection.update(update.to_sql)
@transition_class.connection.update(update.to_sql)
end

def most_recent_transitions(most_recent_id = nil)
Expand Down Expand Up @@ -237,7 +242,7 @@ def build_arel_manager(manager)
if manager.instance_method(:initialize).arity.zero?
manager.new
else
manager.new(::ActiveRecord::Base)
manager.new(@transition_class)
end
end

Expand All @@ -258,7 +263,7 @@ def transition_conflict_error?(err)
end

def unique_indexes
::ActiveRecord::Base.connection.
@transition_class.connection.
indexes(transition_class.table_name).
select do |index|
next unless index.unique
Expand Down Expand Up @@ -326,19 +331,20 @@ def default_timezone
return ::ActiveRecord.default_timezone
end

::ActiveRecord::Base.default_timezone
# TODO: In light of the comment above, consider deprecating?
@transition_class.default_timezone
end

def mysql_gaplock_protection?
Statesman.mysql_gaplock_protection?
end

def db_true
::ActiveRecord::Base.connection.quote(type_cast(true))
@transition_class.connection.quote(type_cast(true))
end

def db_false
::ActiveRecord::Base.connection.quote(type_cast(false))
@transition_class.connection.quote(type_cast(false))
end

def db_null
Expand All @@ -348,7 +354,8 @@ def db_null
# Type casting against a column is deprecated and will be removed in Rails 6.2.
# See https://github.com/rails/arel/commit/6160bfbda1d1781c3b08a33ec4955f170e95be11
def type_cast(value)
::ActiveRecord::Base.connection.type_cast(value)
# TODO: See if this should be deprecated based on above comment.
@transition_class.connection.type_cast(value)
end

# Check whether the `most_recent` column allows null values. If it doesn't, set old
Expand All @@ -368,9 +375,9 @@ def not_most_recent_value(db_cast: true)
end

class ActiveRecordAfterCommitWrap
def initialize(&block)
def initialize(connection, &block)
@callback = block
@connection = ::ActiveRecord::Base.connection
@connection = connection
end

def self.trigger_transactional_callbacks?
Expand Down

0 comments on commit 9941f41

Please sign in to comment.