Giter VIP home page Giter VIP logo

dm-relation-graph's Introduction

Relation Graph

BuildStatus DependencyStatus CodeClimate

API (not yet implemented, open for suggestions, RDD style)

graph = DataMapper::Relation::Graph.new do

  base_relation :people do

    # only base relation node builders expose this method
    #
    repository :postgres

    attribute :id,        Integer
    attribute :parent_id, Integer
    attribute :name,      String
    attribute :birthday,  Date

    key id

    # creates an instance of Reference and a
    # corresponding many_to_one relationship
    #
    # aliased to #many_to_one
    references :parent, parent_id => id

    one_to_one :profile, profiles.reference(:person)

    one_to_many :children, reference(:parent)

    # arbitrary params can be passed to the block in order
    # to be able to compose parameterized scopes. this is
    # true for all relationship types, not only one_to_many
    one_to_many :teenagers, reference(:parent) do |date|
      restrict { |r| r.birthday.lte(date) }
    end

    one_to_many :addresses, addresses.reference(:person)

    # ALTERNATIVE 1

    # through relationship exists

    one_to_many :links_to_followers, people_links.reference(:followed)

    many_to_many :followers do

      # if the given parameter is a symbol,
      # lookup the corresponding relationship.
      #
      # passing a reference as first parameter
      # implies going through a one_to_many
      # relationship that may or may not exist.
      #
      # if it doesn't exist, the necessary
      # information to peform the join, is
      # retrieved from the given reference
      # (which essentially is the many_to_one
      # relationship on the "virtual" one_to_many
      # relationship's target end.
      #
      through :links_to_followers do
        # some fancy operation
      end

      # The same constraints as with #through
      # apply also for the #via method.
      #
      via people_links.reference(:follower) do
        # some fancy operation
        #
        # passing a block will raise an error
        # if the given parameter is a reference,
        # as this implies going via a many_to_one
        # relationship and it makes no sense to
        # apply any further operations to that as
        # it points to a uniquely identified tuple.
        #
        # obviously, for the given example, that
        # error would be raised.
      end

      apply do |some, optional, params, here|
        # some fancy operation on the joined relation
      end
    end

    # through relationship does not exist

    many_to_many :followed_people do
      through people_links.reference(:follower)
      via people_links.reference(:followed)
    end

    # ALTERNATIVE 2 (using links)

    many_to_many :followers, people_links.link(:followers) do |optional, params|
      # some fancy operation
    end

    many_to_many :followed_people, people_links.link(:followed_people) do |optional, params|
      # some fancy operation
    end

  end

  base_relation :addresses do

    repository :postgres

    attribute :id,        Integer
    attribute :person_id, Integer
    attribute :street,    String

    key id

    references :person, person_id => people.id
  end

  base_relation :profiles do

    repository :postgres

    attribute :id,        Integer
    attribute :person_id, Integer
    attribute :nickname,  String

    key id

    references :person, person_id => people.id
  end

  base_relation :people_links do

    repository :postgres

    attribute :follower_id, Integer
    attribute :followed_id, Integer

    key follower_id, followed_id

    references :follower, follower_id => people.id
    references :followed, followed_id => people.id

    # links defined for many_to_many ALTERNATIVE 2
    link :followed_people, reference(:follower) => reference(:followed)
    link :followers, reference(:followed) => reference(:follower)
  end

  # register arbitrary relations and give them a name.
  #
  relation :people_with_profiles do
    people.join(profiles, profiles.reference(:person))
  end
end

graph.finalize

people    = graph[:people]
addresses = graph[:addresses]

# return tuples as illustrated by this array of hashes.
# A real implementation would most likely yield (ordered)
# sets containing veritas tuple objects.
#
# [
#   {
#     :id        => 1,
#     :name      => 'John',
#     :addresses => [
#       {
#         :id        => 1,
#         :person_id => 1,
#         :street    => '@home'
#       }
#     ]
#   }
# ]
relation = people.include(:addresses)

# The following explicit join represents an equivalent relation
relation = people.join(addresses, addresses.reference(:person))

# When Graph#relation gets invoked with no arguments but
# receives a block, an "anonymous" relation will be created,
# and the returned relation won't be stored in the graph.
relation = graph.relation do

  # no need to define variables for people and addresses

  people.include(:addresses)

  # The following explicit join represents an equivalent relation
  # It would be rather inconvenient to write outside of the block's
  # evaluator context, as it would involve either using Graph#[]
  # multiple times or introducing (local) variables (as shown above)
  people.join(addresses, addresses.reference(:person))
end

relation.to_a.each do |tuple|
  # ...
end

dm-relation-graph's People

Contributors

snusnu avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.