rom 5.2.4 → 6.0.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +86 -1
 - data/LICENSE +1 -1
 - data/README.md +6 -6
 - data/lib/rom/array_dataset.rb +46 -0
 - data/lib/rom/associations/abstract.rb +217 -0
 - data/lib/rom/associations/definitions/abstract.rb +150 -0
 - data/lib/rom/associations/definitions/many_to_many.rb +29 -0
 - data/lib/rom/associations/definitions/many_to_one.rb +14 -0
 - data/lib/rom/associations/definitions/one_to_many.rb +14 -0
 - data/lib/rom/associations/definitions/one_to_one.rb +14 -0
 - data/lib/rom/associations/definitions/one_to_one_through.rb +14 -0
 - data/lib/rom/associations/definitions.rb +7 -0
 - data/lib/rom/associations/many_to_many.rb +128 -0
 - data/lib/rom/associations/many_to_one.rb +65 -0
 - data/lib/rom/associations/one_to_many.rb +65 -0
 - data/lib/rom/associations/one_to_one.rb +13 -0
 - data/lib/rom/associations/one_to_one_through.rb +13 -0
 - data/lib/rom/associations/through_identifier.rb +41 -0
 - data/lib/rom/attribute.rb +425 -0
 - data/lib/rom/auto_curry.rb +70 -0
 - data/lib/rom/cache.rb +87 -0
 - data/lib/rom/changeset/associated.rb +110 -0
 - data/lib/rom/changeset/create.rb +18 -0
 - data/lib/rom/changeset/delete.rb +15 -0
 - data/lib/rom/changeset/extensions/relation.rb +26 -0
 - data/lib/rom/changeset/pipe.rb +81 -0
 - data/lib/rom/changeset/pipe_registry.rb +27 -0
 - data/lib/rom/changeset/stateful.rb +285 -0
 - data/lib/rom/changeset/update.rb +81 -0
 - data/lib/rom/changeset.rb +185 -0
 - data/lib/rom/command.rb +351 -0
 - data/lib/rom/command_compiler.rb +201 -0
 - data/lib/rom/command_proxy.rb +36 -0
 - data/lib/rom/commands/class_interface.rb +236 -0
 - data/lib/rom/commands/composite.rb +55 -0
 - data/lib/rom/commands/create.rb +15 -0
 - data/lib/rom/commands/delete.rb +16 -0
 - data/lib/rom/commands/graph/class_interface.rb +64 -0
 - data/lib/rom/commands/graph/input_evaluator.rb +94 -0
 - data/lib/rom/commands/graph.rb +88 -0
 - data/lib/rom/commands/lazy/create.rb +35 -0
 - data/lib/rom/commands/lazy/delete.rb +39 -0
 - data/lib/rom/commands/lazy/update.rb +46 -0
 - data/lib/rom/commands/lazy.rb +106 -0
 - data/lib/rom/commands/update.rb +16 -0
 - data/lib/rom/commands.rb +5 -0
 - data/lib/rom/compat/auto_registration.rb +115 -0
 - data/lib/rom/compat/auto_registration_strategies/base.rb +29 -0
 - data/lib/rom/compat/auto_registration_strategies/custom_namespace.rb +84 -0
 - data/lib/rom/compat/auto_registration_strategies/no_namespace.rb +33 -0
 - data/lib/rom/compat/auto_registration_strategies/with_namespace.rb +29 -0
 - data/lib/rom/compat/command.rb +74 -0
 - data/lib/rom/compat/components/dsl/schema.rb +130 -0
 - data/lib/rom/compat/components.rb +91 -0
 - data/lib/rom/compat/global.rb +17 -0
 - data/lib/rom/compat/mapper.rb +22 -0
 - data/lib/rom/compat/registries.rb +47 -0
 - data/lib/rom/compat/relation.rb +40 -0
 - data/lib/rom/compat/schema/dsl.rb +260 -0
 - data/lib/rom/compat/setting_proxy.rb +44 -0
 - data/lib/rom/compat/setup.rb +151 -0
 - data/lib/rom/compat/transformer.rb +49 -0
 - data/lib/rom/compat.rb +22 -0
 - data/lib/rom/components/association.rb +26 -0
 - data/lib/rom/components/command.rb +24 -0
 - data/lib/rom/components/core.rb +148 -0
 - data/lib/rom/components/dataset.rb +60 -0
 - data/lib/rom/components/dsl/association.rb +47 -0
 - data/lib/rom/components/dsl/command.rb +60 -0
 - data/lib/rom/components/dsl/core.rb +126 -0
 - data/lib/rom/components/dsl/dataset.rb +33 -0
 - data/lib/rom/components/dsl/gateway.rb +14 -0
 - data/lib/rom/components/dsl/mapper.rb +70 -0
 - data/lib/rom/components/dsl/relation.rb +49 -0
 - data/lib/rom/components/dsl/schema.rb +150 -0
 - data/lib/rom/components/dsl/view.rb +82 -0
 - data/lib/rom/components/dsl.rb +255 -0
 - data/lib/rom/components/gateway.rb +50 -0
 - data/lib/rom/components/mapper.rb +29 -0
 - data/lib/rom/components/provider.rb +160 -0
 - data/lib/rom/components/registry.rb +154 -0
 - data/lib/rom/components/relation.rb +41 -0
 - data/lib/rom/components/schema.rb +61 -0
 - data/lib/rom/components/view.rb +55 -0
 - data/lib/rom/components.rb +55 -0
 - data/lib/rom/configuration_dsl.rb +4 -0
 - data/lib/rom/constants.rb +135 -0
 - data/lib/rom/container.rb +182 -0
 - data/lib/rom/core.rb +125 -0
 - data/lib/rom/data_proxy.rb +97 -0
 - data/lib/rom/enumerable_dataset.rb +70 -0
 - data/lib/rom/gateway.rb +232 -0
 - data/lib/rom/global.rb +56 -0
 - data/lib/rom/header/attribute.rb +190 -0
 - data/lib/rom/header.rb +198 -0
 - data/lib/rom/inferrer.rb +55 -0
 - data/lib/rom/initializer.rb +80 -0
 - data/lib/rom/lint/enumerable_dataset.rb +56 -0
 - data/lib/rom/lint/gateway.rb +120 -0
 - data/lib/rom/lint/linter.rb +79 -0
 - data/lib/rom/lint/spec.rb +22 -0
 - data/lib/rom/lint/test.rb +98 -0
 - data/lib/rom/loader.rb +161 -0
 - data/lib/rom/mapper/attribute_dsl.rb +480 -0
 - data/lib/rom/mapper/dsl.rb +107 -0
 - data/lib/rom/mapper/model_dsl.rb +61 -0
 - data/lib/rom/mapper.rb +99 -0
 - data/lib/rom/mapper_compiler.rb +84 -0
 - data/lib/rom/memory/associations/many_to_many.rb +12 -0
 - data/lib/rom/memory/associations/many_to_one.rb +12 -0
 - data/lib/rom/memory/associations/one_to_many.rb +12 -0
 - data/lib/rom/memory/associations/one_to_one.rb +12 -0
 - data/lib/rom/memory/associations.rb +6 -0
 - data/lib/rom/memory/commands.rb +60 -0
 - data/lib/rom/memory/dataset.rb +127 -0
 - data/lib/rom/memory/gateway.rb +66 -0
 - data/lib/rom/memory/mapper_compiler.rb +10 -0
 - data/lib/rom/memory/relation.rb +91 -0
 - data/lib/rom/memory/schema.rb +32 -0
 - data/lib/rom/memory/storage.rb +61 -0
 - data/lib/rom/memory/types.rb +11 -0
 - data/lib/rom/memory.rb +7 -0
 - data/lib/rom/model_builder.rb +103 -0
 - data/lib/rom/open_struct.rb +112 -0
 - data/lib/rom/pipeline.rb +111 -0
 - data/lib/rom/plugin.rb +130 -0
 - data/lib/rom/plugins/class_methods.rb +37 -0
 - data/lib/rom/plugins/command/schema.rb +45 -0
 - data/lib/rom/plugins/command/timestamps.rb +149 -0
 - data/lib/rom/plugins/dsl.rb +53 -0
 - data/lib/rom/plugins/relation/changeset.rb +97 -0
 - data/lib/rom/plugins/relation/instrumentation.rb +66 -0
 - data/lib/rom/plugins/relation/registry_reader.rb +36 -0
 - data/lib/rom/plugins/schema/timestamps.rb +59 -0
 - data/lib/rom/plugins.rb +100 -0
 - data/lib/rom/processor/composer.rb +37 -0
 - data/lib/rom/processor/transformer.rb +415 -0
 - data/lib/rom/processor.rb +30 -0
 - data/lib/rom/registries/associations.rb +26 -0
 - data/lib/rom/registries/commands.rb +11 -0
 - data/lib/rom/registries/container.rb +12 -0
 - data/lib/rom/registries/datasets.rb +21 -0
 - data/lib/rom/registries/gateways.rb +8 -0
 - data/lib/rom/registries/mappers.rb +21 -0
 - data/lib/rom/registries/nestable.rb +32 -0
 - data/lib/rom/registries/relations.rb +8 -0
 - data/lib/rom/registries/root.rb +203 -0
 - data/lib/rom/registries/schemas.rb +44 -0
 - data/lib/rom/registries/views.rb +11 -0
 - data/lib/rom/relation/class_interface.rb +61 -0
 - data/lib/rom/relation/combined.rb +160 -0
 - data/lib/rom/relation/commands.rb +65 -0
 - data/lib/rom/relation/composite.rb +53 -0
 - data/lib/rom/relation/curried.rb +129 -0
 - data/lib/rom/relation/graph.rb +107 -0
 - data/lib/rom/relation/loaded.rb +136 -0
 - data/lib/rom/relation/materializable.rb +62 -0
 - data/lib/rom/relation/name.rb +122 -0
 - data/lib/rom/relation/wrap.rb +64 -0
 - data/lib/rom/relation.rb +625 -0
 - data/lib/rom/repository/class_interface.rb +162 -0
 - data/lib/rom/repository/relation_reader.rb +48 -0
 - data/lib/rom/repository/root.rb +75 -0
 - data/lib/rom/repository/session.rb +60 -0
 - data/lib/rom/repository.rb +179 -0
 - data/lib/rom/schema/associations_dsl.rb +222 -0
 - data/lib/rom/schema/inferrer.rb +106 -0
 - data/lib/rom/schema.rb +471 -0
 - data/lib/rom/settings.rb +141 -0
 - data/lib/rom/setup.rb +297 -0
 - data/lib/rom/struct.rb +99 -0
 - data/lib/rom/struct_compiler.rb +114 -0
 - data/lib/rom/support/configurable.rb +213 -0
 - data/lib/rom/support/inflector.rb +31 -0
 - data/lib/rom/support/memoizable.rb +61 -0
 - data/lib/rom/support/notifications.rb +238 -0
 - data/lib/rom/transaction.rb +26 -0
 - data/lib/rom/transformer.rb +46 -0
 - data/lib/rom/types.rb +74 -0
 - data/lib/rom/version.rb +1 -1
 - data/lib/rom-changeset.rb +4 -0
 - data/lib/rom-core.rb +3 -0
 - data/lib/rom-repository.rb +4 -0
 - data/lib/rom.rb +3 -3
 - metadata +276 -39
 
| 
         @@ -0,0 +1,128 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "rom/types"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "rom/associations/abstract"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module ROM
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Associations
         
     | 
| 
      
 8 
     | 
    
         
            +
                # Abstract many-to-many association type
         
     | 
| 
      
 9 
     | 
    
         
            +
                #
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 11 
     | 
    
         
            +
                class ManyToMany < Abstract
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # @!attribute [r] join_relation
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   @return [Relation] Intermediate join relation
         
     | 
| 
      
 14 
     | 
    
         
            +
                  attr_reader :join_relation
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def initialize(*)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    super
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @join_relation = relations[through]
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  # Adapters should implement this method
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # @abstract
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 28 
     | 
    
         
            +
                  def call(*)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # Return configured or inferred FK name
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 35 
     | 
    
         
            +
                  #
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def foreign_key
         
     | 
| 
      
 38 
     | 
    
         
            +
                    definition.foreign_key || join_relation.foreign_key(source.name)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  # Return join-relation name
         
     | 
| 
      
 42 
     | 
    
         
            +
                  #
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 44 
     | 
    
         
            +
                  #
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 46 
     | 
    
         
            +
                  def through
         
     | 
| 
      
 47 
     | 
    
         
            +
                    definition.through
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  # Return parent's relation combine keys
         
     | 
| 
      
 51 
     | 
    
         
            +
                  #
         
     | 
| 
      
 52 
     | 
    
         
            +
                  # @return [Hash<Symbol=>Symbol>]
         
     | 
| 
      
 53 
     | 
    
         
            +
                  #
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 55 
     | 
    
         
            +
                  def parent_combine_keys
         
     | 
| 
      
 56 
     | 
    
         
            +
                    target.associations[source.name].combine_keys.to_a.flatten(1)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  # Associate child tuples with the provided parent
         
     | 
| 
      
 60 
     | 
    
         
            +
                  #
         
     | 
| 
      
 61 
     | 
    
         
            +
                  # @param [Array<Hash>] children An array with child tuples
         
     | 
| 
      
 62 
     | 
    
         
            +
                  # @param [Array,Hash] parent An array with parent tuples or a single tuple
         
     | 
| 
      
 63 
     | 
    
         
            +
                  #
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # @return [Array<Hash>]
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #
         
     | 
| 
      
 66 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def associate(children, parent)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    ((spk, sfk), (tfk, tpk)) = join_key_map
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    case parent
         
     | 
| 
      
 71 
     | 
    
         
            +
                    when Array
         
     | 
| 
      
 72 
     | 
    
         
            +
                      parent.map { |p| associate(children, p) }.flatten(1)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    else
         
     | 
| 
      
 74 
     | 
    
         
            +
                      children.map { |tuple|
         
     | 
| 
      
 75 
     | 
    
         
            +
                        {sfk => tuple.fetch(spk), tfk => parent.fetch(tpk)}
         
     | 
| 
      
 76 
     | 
    
         
            +
                      }
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  # Primary key name on the source side
         
     | 
| 
      
 83 
     | 
    
         
            +
                  #
         
     | 
| 
      
 84 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 85 
     | 
    
         
            +
                  #
         
     | 
| 
      
 86 
     | 
    
         
            +
                  # @api protected
         
     | 
| 
      
 87 
     | 
    
         
            +
                  def source_key
         
     | 
| 
      
 88 
     | 
    
         
            +
                    source.primary_key
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  # Foreign key name on the target side
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #
         
     | 
| 
      
 93 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 94 
     | 
    
         
            +
                  #
         
     | 
| 
      
 95 
     | 
    
         
            +
                  # @api protected
         
     | 
| 
      
 96 
     | 
    
         
            +
                  def target_key
         
     | 
| 
      
 97 
     | 
    
         
            +
                    foreign_key
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  # Return association for many-to-many-through
         
     | 
| 
      
 101 
     | 
    
         
            +
                  #
         
     | 
| 
      
 102 
     | 
    
         
            +
                  # @return [Association]
         
     | 
| 
      
 103 
     | 
    
         
            +
                  #
         
     | 
| 
      
 104 
     | 
    
         
            +
                  # @api protected
         
     | 
| 
      
 105 
     | 
    
         
            +
                  def join_assoc
         
     | 
| 
      
 106 
     | 
    
         
            +
                    if join_relation.associations.key?(through.assoc_name)
         
     | 
| 
      
 107 
     | 
    
         
            +
                      join_relation.associations[through.assoc_name]
         
     | 
| 
      
 108 
     | 
    
         
            +
                    else
         
     | 
| 
      
 109 
     | 
    
         
            +
                      join_relation.associations[through.target]
         
     | 
| 
      
 110 
     | 
    
         
            +
                    end
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  # Return a [pk, fk] mapping for source/target relations
         
     | 
| 
      
 114 
     | 
    
         
            +
                  #
         
     | 
| 
      
 115 
     | 
    
         
            +
                  # @return [Array<Symbol>]
         
     | 
| 
      
 116 
     | 
    
         
            +
                  #
         
     | 
| 
      
 117 
     | 
    
         
            +
                  # @api protected
         
     | 
| 
      
 118 
     | 
    
         
            +
                  def join_key_map
         
     | 
| 
      
 119 
     | 
    
         
            +
                    left = super
         
     | 
| 
      
 120 
     | 
    
         
            +
                    right = join_assoc.join_key_map
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                    [left, right]
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  memoize :foreign_key, :join_assoc, :join_key_map
         
     | 
| 
      
 126 
     | 
    
         
            +
                end
         
     | 
| 
      
 127 
     | 
    
         
            +
              end
         
     | 
| 
      
 128 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "rom/associations/abstract"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ROM
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Associations
         
     | 
| 
      
 7 
     | 
    
         
            +
                # Abstract many-to-one association type
         
     | 
| 
      
 8 
     | 
    
         
            +
                #
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 10 
     | 
    
         
            +
                class ManyToOne < Abstract
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # Adapters must implement this method
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @abstract
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def call(*)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  # Return configured or inferred FK name
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def foreign_key
         
     | 
| 
      
 26 
     | 
    
         
            +
                    definition.foreign_key || source.foreign_key(target.name)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  # Associate child with a parent
         
     | 
| 
      
 30 
     | 
    
         
            +
                  #
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # @param [Hash] child The child tuple
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @param [Hash] parent The parent tuple
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 35 
     | 
    
         
            +
                  #
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def associate(child, parent)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    fk, pk = join_key_map
         
     | 
| 
      
 39 
     | 
    
         
            +
                    child.merge(fk => parent.fetch(pk))
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  # Return foreign key on the source side
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # @api protected
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def source_key
         
     | 
| 
      
 50 
     | 
    
         
            +
                    foreign_key
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  # Return primary key on the target side
         
     | 
| 
      
 54 
     | 
    
         
            +
                  #
         
     | 
| 
      
 55 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 56 
     | 
    
         
            +
                  #
         
     | 
| 
      
 57 
     | 
    
         
            +
                  # @api protected
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def target_key
         
     | 
| 
      
 59 
     | 
    
         
            +
                    target.schema.primary_key_name
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  memoize :foreign_key
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "rom/associations/abstract"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ROM
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Associations
         
     | 
| 
      
 7 
     | 
    
         
            +
                # Abstract one-to-many association
         
     | 
| 
      
 8 
     | 
    
         
            +
                #
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 10 
     | 
    
         
            +
                class OneToMany < Abstract
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # Adapters must implement this method
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @abstract
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def call(*)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    raise NotImplementedError
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  # Return configured or inferred FK name
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def foreign_key
         
     | 
| 
      
 26 
     | 
    
         
            +
                    definition.foreign_key || target.foreign_key(source.name)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  # Associate child tuple with a parent
         
     | 
| 
      
 30 
     | 
    
         
            +
                  #
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # @param [Hash] child The child tuple
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @param [Hash] parent The parent tuple
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # @return [Hash]
         
     | 
| 
      
 35 
     | 
    
         
            +
                  #
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def associate(child, parent)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    pk, fk = join_key_map
         
     | 
| 
      
 39 
     | 
    
         
            +
                    child.merge(fk => parent.fetch(pk))
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  # Return primary key on the source side
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # @api protected
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def source_key
         
     | 
| 
      
 50 
     | 
    
         
            +
                    source.schema.primary_key_name
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  # Return foreign key name on the target side
         
     | 
| 
      
 54 
     | 
    
         
            +
                  #
         
     | 
| 
      
 55 
     | 
    
         
            +
                  # @return [Symbol]
         
     | 
| 
      
 56 
     | 
    
         
            +
                  #
         
     | 
| 
      
 57 
     | 
    
         
            +
                  # @api protected
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def target_key
         
     | 
| 
      
 59 
     | 
    
         
            +
                    foreign_key
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  memoize :foreign_key
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "rom/support/inflector"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module ROM
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Associations
         
     | 
| 
      
 7 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 8 
     | 
    
         
            +
                class ThroughIdentifier
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 10 
     | 
    
         
            +
                  attr_reader :source
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 13 
     | 
    
         
            +
                  attr_reader :target
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 16 
     | 
    
         
            +
                  attr_reader :assoc_name
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def self.[](source, target, assoc_name = nil, inflector: Inflector)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    new(source, target, assoc_name || default_assoc_name(target, inflector: inflector))
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def self.default_assoc_name(relation, inflector:)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    inflector.singularize(relation).to_sym
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def initialize(source, target, assoc_name)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @source = source
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @target = target
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @assoc_name = assoc_name
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 36 
     | 
    
         
            +
                  def to_sym
         
     | 
| 
      
 37 
     | 
    
         
            +
                    source
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     |