Class: ROM::Command

Inherits:
Object
  • Object
show all
Extended by:
Dry::Core::ClassAttributes, ClassInterface, Initializer
Includes:
Commands, Pipeline::Operator
Defined in:
core/lib/rom/command.rb,
core/lib/rom/commands/class_interface.rb

Overview

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

Defined Under Namespace

Modules: ClassInterface

Constant Summary collapse

CommandType =
Types::Strict::Symbol.enum(:create, :update, :delete)
Result =
Types::Strict::Symbol.enum(:one, :many)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#after(*hooks) ⇒ Command (readonly)

Return a new command with appended after hooks

Parameters:

  • hooks (Array<Hash>)

    A list of after hooks configurations

Returns:



226
# File 'core/lib/rom/command.rb', line 226

option :after, Types::Coercible::Array, reader: false, default: -> { self.class.after }

#before(*hooks) ⇒ Command (readonly)

Return a new command with appended before hooks

Parameters:

  • hooks (Array<Hash>)

    A list of before hooks configurations

Returns:



222
# File 'core/lib/rom/command.rb', line 222

option :before, Types::Coercible::Array, reader: false, default: -> { self.class.before }

#curry_argsArray (readonly)

Returns Curried args.

Returns:

  • (Array)

    Curried args



218
# File 'core/lib/rom/command.rb', line 218

option :curry_args, default: -> { EMPTY_ARRAY }

#inputProc, #call (readonly)

Returns Tuple processing function, typically uses Relation#input_schema.

Returns:

  • (Proc, #call)

    Tuple processing function, typically uses Relation#input_schema



214
# File 'core/lib/rom/command.rb', line 214

option :input

#relationRelation (readonly)

Returns Command's relation.

Returns:



195
# File 'core/lib/rom/command.rb', line 195

param :relation

#resultSymbol (readonly)

Returns Result type, either :one or :many.

Returns:

  • (Symbol)

    Result type, either :one or :many



210
# File 'core/lib/rom/command.rb', line 210

option :result, type: Result

#sourceRelation (readonly)

Returns The source relation.

Returns:



206
# File 'core/lib/rom/command.rb', line 206

option :source, default: -> { relation }

#typeSymbol (readonly)

Returns The command type, one of :create, :update or :delete.

Returns:

  • (Symbol)

    The command type, one of :create, :update or :delete



202
# File 'core/lib/rom/command.rb', line 202

option :type, type: CommandType, optional: true

Class Method Details

.[](adapter) ⇒ Class Originally defined in module ClassInterface

Return adapter specific sub-class based on the adapter identifier

This is a syntax sugar to make things consistent

Examples:

ROM::Commands::Create[:memory]
# => ROM::Memory::Commands::Create

Parameters:

  • adapter (Symbol)

    identifier

Returns:

  • (Class)

.adapterSymbol .adapter(identifier) ⇒ Object

Get or set adapter identifier

Overloads:

  • .adapterSymbol

    Get adapter identifier

    Examples:

    ROM::Memory::Commands::Create.adapter
    # => :memory

    Returns:

    • (Symbol)
  • .adapter(identifier) ⇒ Object

    Set adapter identifier. This must always match actual adapter identifier that was used to register an adapter.

    Examples:

    module MyAdapter
      class CreateCommand < ROM::Commands::Memory::Create
        adapter :my_adapter
      end
    end


57
# File 'core/lib/rom/command.rb', line 57

defines :adapter

.adapter_namespace(adapter) ⇒ Module Originally defined in module ClassInterface

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return namespaces that contains command subclasses of a specific adapter

Parameters:

  • adapter (Symbol)

    identifier

Returns:

  • (Module)

#after(hook) ⇒ Array<Hash, Symbol> #after(hook_opts) ⇒ Array<Hash, Symbol> Originally defined in module ClassInterface

Set after-execute hooks

Overloads:

  • #after(hook) ⇒ Array<Hash, Symbol>

    Set an after hook as a method name

    Examples:

    class CreateUser < ROM::Commands::Create[:sql]
      relation :users
      register_as :create
    
      after :my_hook
    
      def my_hook(tuple, *)
        puts "hook called#
      end
    end
  • #after(hook_opts) ⇒ Array<Hash, Symbol>

    Set an after hook as a method name with arguments

    Examples:

    class CreateUser < ROM::Commands::Create[:sql]
      relation :users
      register_as :create
    
      after my_hook: { arg1: 1, arg1: 2 }
    
      def my_hook(tuple, arg1:, arg2:)
        puts "hook called with args: #{arg1} and #{arg2}"
      end
    end

    Parameters:

    • hook (Hash<Symbol=>Hash>)

      Options with method name and pre-set args

Returns:

  • (Array<Hash, Symbol>)

    A list of all configured after hooks

#before(hook) ⇒ Array<Hash, Symbol> #before(hook_opts) ⇒ Array<Hash, Symbol> Originally defined in module ClassInterface

Set before-execute hooks

Overloads:

  • #before(hook) ⇒ Array<Hash, Symbol>

    Set an before hook as a method name

    Examples:

    class CreateUser < ROM::Commands::Create[:sql]
      relation :users
      register_as :create
    
      before :my_hook
    
      def my_hook(tuple, *)
        puts "hook called#
      end
    end
  • #before(hook_opts) ⇒ Array<Hash, Symbol>

    Set an before hook as a method name with arguments

    Examples:

    class CreateUser < ROM::Commands::Create[:sql]
      relation :users
      register_as :create
    
      before my_hook: { arg1: 1, arg2: 2 }
    
      def my_hook(tuple, arg1:, arg2:)
        puts "hook called with args: #{arg1} and #{arg2}"
      end
    end

    Parameters:

    • hook (Hash<Symbol=>Hash>)

      Options with method name and pre-set args

Returns:

  • (Array<Hash, Symbol>)

    A list of all configured before hooks

.build(relation, **options) ⇒ Command Originally defined in module ClassInterface

Build a command class for a specific relation with options

Examples:

class CreateUser < ROM::Commands::Create[:memory]
end

command = CreateUser.build(rom.relations[:users])

Parameters:

Returns:

.create_class(name, type) {|Class| ... } ⇒ Class, Object Originally defined in module ClassInterface

Create a command class with a specific type

Parameters:

  • name (Symbol)

    Command name

  • type (Class)

    Command class

Yields:

  • (Class)

Returns:

  • (Class, Object)

.default_nameSymbol Originally defined in module ClassInterface

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return default name of the command class based on its name

During setup phase this is used by defalut as register_as option

Returns:

  • (Symbol)

.extend_for_relation(relation) ⇒ Class Originally defined in module ClassInterface

Extend a command class with relation view methods

Parameters:

Returns:

  • (Class)

.inherited(klass) ⇒ Object Originally defined in module ClassInterface

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This hook sets up default class state

.inputProc, #call .input(identifier) ⇒ Object

Get or set input processing function. This is typically set during setup to relation's input_schema

Overloads:

  • .inputProc, #call

    Get input processing function

    Examples:

    class CreateUser < ROM::Commands::Create[:memory]
      input -> tuple { .. }
    end
    
    CreateUser.input
    # Your custom function

    Returns:

  • .input(identifier) ⇒ Object

    Set input processing function

    Examples:

    class CreateUser < ROM::Commands::Create[:memory]
      input -> tuple { .. }
    end


139
# File 'core/lib/rom/command.rb', line 139

defines :input

.optionsHash Originally defined in module ClassInterface

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return default options based on class macros

Returns:

  • (Hash)

.register_asSymbol .register_as(identifier) ⇒ Object

Get or set identifier that should be used to register a command in a container

Overloads:

  • .register_asSymbol

    Get registration identifier

    Examples:

    class CreateUser < ROM::Commands::Create[:memory]
      register_as :create_user
    end
    
    CreateUser.register_as
    # => :create_user

    Returns:

    • (Symbol)
  • .register_as(identifier) ⇒ Object

    Set registration identifier

    Examples:

    class CreateUser < ROM::Commands::Create[:memory]
      register_as :create_user
    end


166
# File 'core/lib/rom/command.rb', line 166

defines :register_as

.relationSymbol .relation(identifier) ⇒ Object

Get or set relation identifier

Overloads:

  • .relationSymbol

    Get relation identifier

    Examples:

    class CreateUser < ROM::Commands::Create[:memory]
      relation :users
    end
    
    CreateUser.relation
    # => :users

    Returns:

    • (Symbol)
  • .relation(identifier) ⇒ Object

    Set relation identifier.

    Examples:

    class CreateUser < ROM::Commands::Create[:memory]
      relation :users
    end


84
# File 'core/lib/rom/command.rb', line 84

defines :relation

.relation_methods_mod(relation_class) ⇒ Object Originally defined in module ClassInterface

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

.restrictableFalseClass, TrueClass .restrictable(value) ⇒ Object

Overloads:

  • .restrictableFalseClass, TrueClass

    Check if a command class is restrictable

    Examples:

    class UpdateUser < ROM::Commands::Update[:memory]
      restrictable true
    end
    
    CreateUser.restrictable
    # => true

    Returns:

    • (FalseClass, TrueClass)
  • .restrictable(value) ⇒ Object

    Set if a command is restrictable

    Examples:

    class UpdateUser < ROM::Commands::Update[:memory]
      restrictable true
    end


191
# File 'core/lib/rom/command.rb', line 191

defines :restrictable

.resultSymbol .result(identifier) ⇒ Object

Get or set result type

Overloads:

  • .resultSymbol

    Get result type

    Examples:

    class CreateUser < ROM::Commands::Create[:memory]
      result :one
    end
    
    CreateUser.result
    # => :one

    Returns:

    • (Symbol)
  • .result(identifier) ⇒ Object

    Set result type

    Examples:

    class CreateUser < ROM::Commands::Create[:memory]
      result :one
    end


111
# File 'core/lib/rom/command.rb', line 111

defines :result

.set_hooks(type, hooks) ⇒ Object Originally defined in module ClassInterface

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Set new or more hooks

.use(plugin, **options) ⇒ Object Originally defined in module ClassInterface

Use a configured plugin in this relation

Examples:

class CreateUser < ROM::Commands::Create[:memory]
  use :pagintion

  per_page 30
end

Parameters:

  • plugin (Symbol)
  • options (Hash)

Options Hash (**options):

  • :adapter (Symbol) — default: :default

    first adapter to check for plugin

Instance Method Details

#>>(other) ⇒ Relation::Composite Originally defined in module Pipeline::Operator

Compose two relation with a left-to-right composition

Examples:

users.by_name('Jane') >> tasks.for_users

Parameters:

  • other (Relation)

    The right relation

Returns:

#after_hooksArray

List of after hooks

Returns:

  • (Array)


375
376
377
# File 'core/lib/rom/command.rb', line 375

def after_hooks
  options[:after]
end

#before_hooksArray

List of before hooks

Returns:

  • (Array)


366
367
368
# File 'core/lib/rom/command.rb', line 366

def before_hooks
  options[:before]
end

#call(*args, &block) ⇒ Object Also known as: []

Call the command and return one or many tuples

This method will apply before/after hooks automatically



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'core/lib/rom/command.rb', line 268

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

#combine(*others) ⇒ Command::Graph

Compose this command with other commands

Composed commands can handle nested input

Returns:



326
327
328
# File 'core/lib/rom/command.rb', line 326

def combine(*others)
  Graph.new(self, others)
end

#curried?TrueClass, FalseClass

Check if this command is curried

Returns:

  • (TrueClass, FalseClass)


335
336
337
# File 'core/lib/rom/command.rb', line 335

def curried?
  !curry_args.empty?
end

#curry(*args) ⇒ Command, Lazy

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.

Returns:



311
312
313
314
315
316
317
# File 'core/lib/rom/command.rb', line 311

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

#executeArray

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method is abstract.

Execute the command

Returns:

  • (Array)

    an array with inserted tuples

Raises:

  • (NotImplementedError)


256
257
258
259
260
261
# File 'core/lib/rom/command.rb', line 256

def execute(*)
  raise(
    NotImplementedError,
    "#{self.class}##{__method__} must be implemented"
  )
end

#gatewaySymbol

Return gateway of this command's relation

Returns:

  • (Symbol)


245
246
247
# File 'core/lib/rom/command.rb', line 245

def gateway
  relation.gateway
end

#graph?false

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this command is a graph

Returns:

  • (false)


411
412
413
# File 'core/lib/rom/command.rb', line 411

def graph?
  false
end

#hooks?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this command has any hooks

Returns:

  • (Boolean)


393
394
395
# File 'core/lib/rom/command.rb', line 393

def hooks?
  !before_hooks.empty? || !after_hooks.empty?
end

#lazy?false

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this command is lazy

Returns:

  • (false)


402
403
404
# File 'core/lib/rom/command.rb', line 402

def lazy?
  false
end

#many?TrueClass, FalseClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this command returns many tuples

Returns:

  • (TrueClass, FalseClass)


429
430
431
# File 'core/lib/rom/command.rb', line 429

def many?
  result.equal?(:many)
end

#map_input_tuples(tuples, &mapper) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Yields tuples for insertion or return an enumerator



445
446
447
448
449
450
451
452
453
# File 'core/lib/rom/command.rb', line 445

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

#nameROM::Relation::Name

Return name of this command's relation

Returns:



236
237
238
# File 'core/lib/rom/command.rb', line 236

def name
  relation.name
end

#new(new_relation) ⇒ Command

Return a new command with other source relation

This can be used to restrict command with a specific relation

Returns:



386
387
388
# File 'core/lib/rom/command.rb', line 386

def new(new_relation)
  self.class.build(new_relation, **options, source: relation)
end

#one?TrueClass, FalseClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this command returns a single tuple

Returns:

  • (TrueClass, FalseClass)


420
421
422
# File 'core/lib/rom/command.rb', line 420

def one?
  result.equal?(:one)
end

#restrictible?TrueClass, FalseClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this command is restrictible through relation

Returns:

  • (TrueClass, FalseClass)


438
439
440
# File 'core/lib/rom/command.rb', line 438

def restrictible?
  self.class.restrictable.equal?(true)
end