lib/rom/ra.rb in rom-0.4.1 vs lib/rom/ra.rb in rom-0.4.2

- old
+ new

@@ -7,189 +7,165 @@ # Experimental DSL for in-memory relational operations # # @api private module RA - # Exposes in-memory relational operations + # Join two relations in-memory using natural-join # - # See examples for join, group and wrap operations + # @example # + # require 'rom' + # require 'rom/adapter/memory' + # + # setup = ROM.setup(memory: 'memory://localhost') + # + # setup.schema do + # base_relation(:users) do + # repository :memory + # + # attribute :user_id + # attribute :name + # end + # + # base_relation(:tasks) do + # repository :memory + # + # attribute :user_id + # attribute :title + # end + # end + # + # setup.relation(:tasks) + # + # setup.relation(:users) do + # def with_tasks + # in_memory { join(tasks) } + # end + # end + # + # rom.relations.users.insert user_id: 1, name: 'Piotr' + # rom.relations.tasks.insert user_id: 1, title: 'Relax' + # + # rom.relations.users.with_tasks.to_a + # => [{:user_id=>1, :name=>"Piotr", :title=>"Relax"}] + # # @api public - def in_memory(&block) - DSL.new(self).instance_exec(&block) + def join(*args) + left, right = args.size > 1 ? args : [self, args.first] + Operation::Join.new(left, right) end - class DSL - include Concord.new(:relation) + # Groups two relations in-memory using group operation + # + # @example + # + # require 'rom' + # require 'rom/adapter/memory' + # + # setup = ROM.setup(memory: 'memory://localhost') + # + # setup.schema do + # base_relation(:users) do + # repository :memory + # + # attribute :user_id + # attribute :name + # end + # + # base_relation(:tasks) do + # repository :memory + # + # attribute :user_id + # attribute :title + # end + # end + # + # setup.relation(:tasks) + # + # setup.relation(:users) do + # def with_tasks + # in_memory { group(join(tasks), tasks: [:title]) } + # end + # end + # + # rom.relations.users.insert user_id: 1, name: 'Piotr' + # rom.relations.tasks.insert user_id: 1, title: 'Work' + # rom.relations.tasks.insert user_id: 1, title: 'Relax' + # + # rom.relations.users.with_tasks.to_a + # => [{:user_id=>1, :name=>"Piotr", tasks: [{:title=>"Relax"}, {:title=>"Work"}]}] + # + # @api public + def group(*args) + ra_with_options(*args) { |relation, options| + Operation::Group.new(relation, options) + } + end - # Join two relations in-memory using natural-join - # - # @example - # - # require 'rom' - # require 'rom/adapter/memory' - # - # setup = ROM.setup(memory: 'memory://localhost') - # - # setup.schema do - # base_relation(:users) do - # repository :memory - # - # attribute :user_id - # attribute :name - # end - # - # base_relation(:tasks) do - # repository :memory - # - # attribute :user_id - # attribute :title - # end - # end - # - # setup.relation(:tasks) - # - # setup.relation(:users) do - # def with_tasks - # in_memory { join(tasks) } - # end - # end - # - # rom.relations.users.insert user_id: 1, name: 'Piotr' - # rom.relations.tasks.insert user_id: 1, title: 'Relax' - # - # rom.relations.users.with_tasks.to_a - # => [{:user_id=>1, :name=>"Piotr", :title=>"Relax"}] - # - # @api public - def join(*args) - left, right = args.size > 1 ? args : [relation, args.first] - Operation::Join.new(left, right) - end + # Embed one relation in another in-memory using wrap operation + # + # @example + # + # require 'rom' + # require 'rom/adapter/memory' + # + # setup = ROM.setup(memory: 'memory://localhost') + # + # setup.schema do + # base_relation(:users) do + # repository :memory + # + # attribute :user_id + # attribute :name + # end + # + # base_relation(:addresses) do + # repository :memory + # + # attribute :user_id + # attribute :street + # attribute :zipcode + # attribute :city + # end + # end + # + # setup.relation(:addresses) + # + # setup.relation(:users) do + # def with_address + # in_memory { wrap(join(addresses), address: [:street, :zipcode, :city]) } + # end + # end + # + # rom = setup.finalize + # + # rom.relations.users.insert user_id: 1, name: 'Piotr' + # rom.relations.addresses.insert user_id: 1, street: 'Street 1', zipcode: '123', city: 'Kraków' + # + # rom.relations.users.with_address.to_a + # => [{:user_id=>1, :name=>"Piotr", :address=>{:street=>"Street 1", :zipcode=>"123", :city=>"Kraków"}}] + # + # @api public + def wrap(*args) + ra_with_options(*args) { |relation, options| + Operation::Wrap.new(relation, options) + } + end - # Groups two relations in-memory using group operation - # - # @example - # - # require 'rom' - # require 'rom/adapter/memory' - # - # setup = ROM.setup(memory: 'memory://localhost') - # - # setup.schema do - # base_relation(:users) do - # repository :memory - # - # attribute :user_id - # attribute :name - # end - # - # base_relation(:tasks) do - # repository :memory - # - # attribute :user_id - # attribute :title - # end - # end - # - # setup.relation(:tasks) - # - # setup.relation(:users) do - # def with_tasks - # in_memory { group(join(tasks), tasks: [:title]) } - # end - # end - # - # rom.relations.users.insert user_id: 1, name: 'Piotr' - # rom.relations.tasks.insert user_id: 1, title: 'Work' - # rom.relations.tasks.insert user_id: 1, title: 'Relax' - # - # rom.relations.users.with_tasks.to_a - # => [{:user_id=>1, :name=>"Piotr", tasks: [{:title=>"Relax"}, {:title=>"Work"}]}] - # - # @api public - def group(*args) - with_options(*args) { |relation, options| - Operation::Group.new(relation, options) - } - end + private - # Embed one relation in another in-memory using wrap operation - # - # @example - # - # require 'rom' - # require 'rom/adapter/memory' - # - # setup = ROM.setup(memory: 'memory://localhost') - # - # setup.schema do - # base_relation(:users) do - # repository :memory - # - # attribute :user_id - # attribute :name - # end - # - # base_relation(:addresses) do - # repository :memory - # - # attribute :user_id - # attribute :street - # attribute :zipcode - # attribute :city - # end - # end - # - # setup.relation(:addresses) - # - # setup.relation(:users) do - # def with_address - # in_memory { wrap(join(addresses), address: [:street, :zipcode, :city]) } - # end - # end - # - # rom = setup.finalize - # - # rom.relations.users.insert user_id: 1, name: 'Piotr' - # rom.relations.addresses.insert user_id: 1, street: 'Street 1', zipcode: '123', city: 'Kraków' - # - # rom.relations.users.with_address.to_a - # => [{:user_id=>1, :name=>"Piotr", :address=>{:street=>"Street 1", :zipcode=>"123", :city=>"Kraków"}}] - # - # @api public - def wrap(*args) - with_options(*args) { |relation, options| - Operation::Wrap.new(relation, options) - } - end + # @api private + def ra_with_options(*args) + relation = + if args.size > 1 + args.first + else + self + end - # @api private - def respond_to_missing?(name, include_private = false) - relation.respond_to?(name) || super - end + options = args.last - private - - # @api private - def with_options(*args) - relation = - if args.size > 1 - args.first - else - self.relation - end - - options = args.last - - yield(relation, options) - end - - # @api private - def method_missing(name, *args, &block) - relation.public_send(name, *args, &block) - end - + yield(relation, options) end end end