Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions lib/octoball/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,18 @@ module ShardedCollectionAssociation
[:writer, :ids_reader, :ids_writer, :create, :create!,
:build, :include?, :load_target, :reload, :size, :select].each do |method|
class_eval <<-"END", __FILE__, __LINE__ + 1
def #{method}(*args, &block)
def #{method}(*args, **kwargs, &block)
shard = owner.current_shard
return super if !shard || shard == ActiveRecord::Base.current_shard
return super(*args, **kwargs, &block) if !shard || shard == ActiveRecord::Base.current_shard
ret = nil
ActiveRecord::Base.connected_to(shard: shard, role: Octoball.current_role) do
ret = super
ret = super(*args, **kwargs, &block)
return ret unless ret.is_a?(::ActiveRecord::Relation) || ret.is_a?(::ActiveRecord::QueryMethods::WhereChain)
ret = RelationProxy.new(ret, shard)
nil # return nil to avoid loading relation
end
ret
end
ruby2_keywords(:#{method}) if respond_to?(:ruby2_keywords, true)
END
end
end
Expand All @@ -51,27 +50,25 @@ module ShardedCollectionProxy
:destroy, :destroy_all, :empty?, :find, :first, :include?, :last, :length,
:many?, :pluck, :replace, :select, :size, :sum, :to_a, :uniq].each do |method|
class_eval <<-"END", __FILE__, __LINE__ + 1
def #{method}(*args, &block)
return super if !@association.owner.current_shard || @association.owner.current_shard == ActiveRecord::Base.current_shard
def #{method}(*args, **kwargs, &block)
return super(*args, **kwargs, &block) if !@association.owner.current_shard || @association.owner.current_shard == ActiveRecord::Base.current_shard
ActiveRecord::Base.connected_to(shard: @association.owner.current_shard, role: Octoball.current_role) do
super
super(*args, **kwargs, &block)
end
end
ruby2_keywords(:#{method}) if respond_to?(:ruby2_keywords, true)
END
end
end

module ShardedSingularAssociation
[:reload, :writer, :create, :create!, :build].each do |method|
class_eval <<-"END", __FILE__, __LINE__ + 1
def #{method}(*args, &block)
return super if !owner.current_shard || owner.current_shard == ActiveRecord::Base.current_shard
def #{method}(*args, **kwargs, &block)
return super(*args, **kwargs, &block) if !owner.current_shard || owner.current_shard == ActiveRecord::Base.current_shard
ActiveRecord::Base.connected_to(shard: owner.current_shard, role: Octoball.current_role) do
super
super(*args, **kwargs, &block)
end
end
ruby2_keywords(:#{method}) if respond_to?(:ruby2_keywords, true)
END
end
end
Expand Down
7 changes: 3 additions & 4 deletions lib/octoball/persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ module ShardedPersistence
[:update_columns, :increment!, :reload, :_delete_row, :_touch_row, :_update_row, :_create_record,
:transaction, :with_transaction_returning_status].each do |method|
class_eval <<-"END", __FILE__, __LINE__ + 1
def #{method}(*args, &block)
return super if !current_shard || current_shard == ActiveRecord::Base.current_shard
def #{method}(*args, **kwargs, &block)
return super(*args, **kwargs, &block) if !current_shard || current_shard == ActiveRecord::Base.current_shard
ActiveRecord::Base.connected_to(shard: current_shard, role: Octoball.current_role) do
super
super(*args, **kwargs, &block)
end
end
ruby2_keywords(:#{method}) if respond_to?(:ruby2_keywords, true)
END
end

Expand Down
20 changes: 9 additions & 11 deletions lib/octoball/relation_proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,51 +33,49 @@ def respond_to?(method, include_all = false)
end + [:each, :map, :index_by]
ENUM_WITH_BLOCK_METHODS = [:find, :select, :none?, :any?, :one?, :many?, :sum]

def method_missing(method, *args, &block)
def method_missing(method, *args, **kwargs, &block)
# raise NoMethodError unless the method is defined in @rel
return @rel.public_send(method, *args, &block) unless @rel.respond_to?(method)
return @rel.public_send(method, *args, **kwargs, &block) unless @rel.respond_to?(method)

preamble = <<-EOS
def #{method}(*margs, &mblock)
return @rel.#{method}(*margs, &mblock) unless @current_shard
def #{method}(*margs, **mkwargs, &mblock)
return @rel.#{method}(*margs, **mkwargs, &mblock) unless @current_shard
EOS
postamble = <<-EOS
return ret unless ret.is_a?(::ActiveRecord::Relation) || ret.is_a?(::ActiveRecord::QueryMethods::WhereChain) || ret.is_a?(::Enumerator)
::Octoball::RelationProxy.new(ret, @current_shard)
end
ruby2_keywords(:#{method}) if respond_to?(:ruby2_keywords, true)
EOS
connected_to = '::ActiveRecord::Base.connected_to(role: ::Octoball.current_role, shard: @current_shard)'

if ENUM_METHODS.include?(method)
::Octoball::RelationProxy.class_eval <<-EOS, __FILE__, __LINE__ - 1
#{preamble}
ret = #{connected_to} { @rel.to_a }.#{method}(*margs, &mblock)
ret = #{connected_to} { @rel.to_a }.#{method}(*margs, **mkwargs, &mblock)
#{postamble}
EOS
elsif ENUM_WITH_BLOCK_METHODS.include?(method)
::Octoball::RelationProxy.class_eval <<-EOS, __FILE__, __LINE__ - 1
#{preamble}
ret = nil
if mblock
ret = #{connected_to} { @rel.to_a }.#{method}(*margs, &mblock)
ret = #{connected_to} { @rel.to_a }.#{method}(*margs, **mkwargs, &mblock)
else
#{connected_to} { ret = @rel.#{method}(*margs, &mblock); nil } # return nil to avoid loading relation
#{connected_to} { ret = @rel.#{method}(*margs, **mkwargs, &mblock); nil } # return nil to avoid loading relation
end
#{postamble}
EOS
else
::Octoball::RelationProxy.class_eval <<-EOS, __FILE__, __LINE__ - 1
#{preamble}
ret = nil
#{connected_to} { ret = @rel.#{method}(*margs, &mblock); nil } # return nil to avoid loading relation
#{connected_to} { ret = @rel.#{method}(*margs, **mkwargs, &mblock); nil } # return nil to avoid loading relation
#{postamble}
EOS
end

public_send(method, *args, &block)
public_send(method, *args, **kwargs, &block)
end
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)

def inspect
return @rel.inspect unless @current_shard
Expand Down