class ROM::Command

Abstract command class

Provides a constructor accepting relation with options and basic behavior for calling, currying and composing commands.

Typically command subclasses should inherit from specialized Create/Update/Delete, not this one.

@abstract

@api public

Base command class with factory class-level interface and setup-related logic

@private

Constants

CommandType
Result

Public Instance Methods

[](*args, &block)
Alias for: call
after(*hooks) click to toggle source

Return a new command with appended after hooks

@param [Array<Hash>] hooks A list of after hooks configurations

@return [Command]

@api public

# File lib/rom/command.rb, line 359
def after(*hooks)
  self.class.new(relation, **options, after: after_hooks + hooks)
end
after_hooks() click to toggle source

List of after hooks

@return [Array]

@api public

# File lib/rom/command.rb, line 377
def after_hooks
  options[:after]
end
before(*hooks) click to toggle source

Return a new command with appended before hooks

@param [Array<Hash>] hooks A list of before hooks configurations

@return [Command]

@api public

# File lib/rom/command.rb, line 348
def before(*hooks)
  self.class.new(relation, **options, before: before_hooks + hooks)
end
before_hooks() click to toggle source

List of before hooks

@return [Array]

@api public

# File lib/rom/command.rb, line 368
def before_hooks
  options[:before]
end
call(*args, &block) click to toggle source

Call the command and return one or many tuples

This method will apply before/after hooks automatically

@api public

# File lib/rom/command.rb, line 270
def call(*args, &block)
  tuples =
    if hooks?
      prepared =
        if curried?
          apply_hooks(before_hooks, *(curry_args + args))
        else
          apply_hooks(before_hooks, *args)
        end

      result = prepared ? execute(prepared, &block) : execute(&block)

      if curried?
        if !args.empty?
          apply_hooks(after_hooks, result, *args)
        elsif curry_args.size > 1
          apply_hooks(after_hooks, result, curry_args[1])
        else
          apply_hooks(after_hooks, result)
        end
      else
        apply_hooks(after_hooks, result, *args[1..args.size - 1])
      end
    else
      execute(*(curry_args + args), &block)
    end

  if one?
    tuples.first
  else
    tuples
  end
end
Also aliased as: []
combine(*others) click to toggle source

Compose this command with other commands

Composed commands can handle nested input

@return [Command::Graph]

@api public

# File lib/rom/command.rb, line 328
def combine(*others)
  Graph.new(self, others)
end
curried?() click to toggle source

Check if this command is curried

@return [TrueClass, FalseClass]

@api public

# File lib/rom/command.rb, line 337
def curried?
  !curry_args.empty?
end
curry(*args) click to toggle source

Curry this command with provided args

Curried command can be called without args. If argument is a graph input processor, lazy command will be returned, which is used for handling nested input hashes.

@return [Command, Lazy]

@api public

# File lib/rom/command.rb, line 313
def curry(*args)
  if curry_args.empty? && args.first.is_a?(Graph::InputEvaluator)
    Lazy[self].new(self, *args)
  else
    self.class.build(relation, **options, curry_args: args)
  end
end
execute(*) click to toggle source

Execute the command

@abstract

@return [Array] an array with inserted tuples

@api private

# File lib/rom/command.rb, line 258
def execute(*)
  raise(
    NotImplementedError,
    "#{self.class}##{__method__} must be implemented"
  )
end
gateway() click to toggle source

Return gateway of this command's relation

@return [Symbol]

@api public

# File lib/rom/command.rb, line 247
def gateway
  relation.gateway
end
graph?() click to toggle source

Check if this command is a graph

@return [false]

@api private

# File lib/rom/command.rb, line 413
def graph?
  false
end
hooks?() click to toggle source

Check if this command has any hooks

@api private

# File lib/rom/command.rb, line 395
def hooks?
  !before_hooks.empty? || !after_hooks.empty?
end
lazy?() click to toggle source

Check if this command is lazy

@return [false]

@api private

# File lib/rom/command.rb, line 404
def lazy?
  false
end
many?() click to toggle source

Check if this command returns many tuples

@return [TrueClass,FalseClass]

@api private

# File lib/rom/command.rb, line 431
def many?
  result.equal?(:many)
end
map_input_tuples(tuples, &mapper) click to toggle source

Yields tuples for insertion or return an enumerator

@api private

# File lib/rom/command.rb, line 447
def map_input_tuples(tuples, &mapper)
  return enum_for(:with_input_tuples, tuples) unless mapper

  if tuples.respond_to? :merge
    mapper[tuples]
  else
    tuples.map(&mapper)
  end
end
name() click to toggle source

Return name of this command's relation

@return [ROM::Relation::Name]

@api public

# File lib/rom/command.rb, line 238
def name
  relation.name
end
new(new_relation) click to toggle source

Return a new command with other source relation

This can be used to restrict command with a specific relation

@return [Command]

@api public

# File lib/rom/command.rb, line 388
def new(new_relation)
  self.class.build(new_relation, **options, source: relation)
end
one?() click to toggle source

Check if this command returns a single tuple

@return [TrueClass,FalseClass]

@api private

# File lib/rom/command.rb, line 422
def one?
  result.equal?(:one)
end
restrictible?() click to toggle source

Check if this command is restrictible through relation

@return [TrueClass,FalseClass]

@api private

# File lib/rom/command.rb, line 440
def restrictible?
  self.class.restrictable.equal?(true)
end

Private Instance Methods

apply_hooks(hooks, tuples, *args) click to toggle source

Apply provided hooks

Used by call

@return [Array<Hash>]

@api private

# File lib/rom/command.rb, line 475
def apply_hooks(hooks, tuples, *args)
  hooks.reduce(tuples) do |a, e|
    if e.is_a?(Hash)
      hook_meth, hook_args = e.to_a.flatten(1)
      __send__(hook_meth, a, *args, **hook_args)
    else
      __send__(e, a, *args)
    end
  end
end
composite_class() click to toggle source

Hook called by Pipeline to get composite class for commands

@return [Class]

@api private

# File lib/rom/command.rb, line 464
def composite_class
  Command::Composite
end
wrap_dataset(dataset) click to toggle source

Pipes a dataset through command's relation

@return [Array]

@api private

# File lib/rom/command.rb, line 491
def wrap_dataset(dataset)
  if relation.is_a?(Relation::Composite)
    relation.new(dataset).to_a
  else
    dataset
  end
end