class NoSE::Connection

Superclass for connect and disconnect statements

Attributes

conditions[R]
source_pk[R]
target[R]
target_pk[R]

Public Class Methods

keys_from_tree(tree, params) click to toggle source

@return

# File lib/nose/statements/connection.rb, line 28
def self.keys_from_tree(tree, params)
  params[:source_pk] = tree[:source_pk]
  params[:target] = params[:entity].foreign_keys[tree[:target].to_s]
  params[:target_pk] = tree[:target_pk]
end
new(params, text, group: nil, label: nil) click to toggle source
Calls superclass method NoSE::Statement::new
# File lib/nose/statements/connection.rb, line 11
def initialize(params, text, group: nil, label: nil)
  super params, text, group: group, label: label
  fail InvalidStatementException, 'Incorrect connection initialization' \
    unless text.split.first == self.class.name.split('::').last.upcase

  populate_conditions params
end
parse(tree, params, text, group: nil, label: nil) click to toggle source

Build a new disconnect from a provided parse tree @return [Connection]

# File lib/nose/statements/connection.rb, line 21
def self.parse(tree, params, text, group: nil, label: nil)
  keys_from_tree tree, params

  new params, text, group: group, label: label
end

Public Instance Methods

==(other) click to toggle source
# File lib/nose/statements/connection.rb, line 41
def ==(other)
  self.class == other.class &&
    @graph == other.graph &&
    @source == other.source &&
    @target == other.target &&
    @conditions == other.conditions
end
Also aliased as: eql?
eql?(other)
Alias for: ==
hash() click to toggle source
# File lib/nose/statements/connection.rb, line 50
def hash
  @hash ||= [@graph, @source, @target, @conditions].hash
end
modifies_index?(index) click to toggle source

A connection modifies an index if the relationship is in the path

# File lib/nose/statements/connection.rb, line 55
def modifies_index?(index)
  index.path.include?(@target) || index.path.include?(@target.reverse)
end
support_queries(index) click to toggle source

Get the support queries for updating an index

# File lib/nose/statements/connection.rb, line 60
def support_queries(index)
  return [] unless modifies_index?(index)

  select = index.all_fields - @conditions.each_value.map(&:field).to_set
  return [] if select.empty?

  index.graph.split(entity).map do |graph|
    support_fields = select.select do |field|
      graph.entities.include? field.parent
    end.to_set
    conditions = @conditions.select do |_, c|
      graph.entities.include? c.field.parent
    end

    split_entity = split_entity graph, index.graph, entity
    build_support_query split_entity, index, graph, support_fields,
                        conditions
  end.compact
end
unparse() click to toggle source

Produce the SQL text corresponding to this connection @return [String]

# File lib/nose/statements/connection.rb, line 36
def unparse
  "CONNECT #{source.name}(\"#{source_pk}\") TO " \
    "#{target.name}(\"#{target_pk}\")"
end

Protected Instance Methods

given_fields() click to toggle source

The two key fields are provided with the connection

# File lib/nose/statements/connection.rb, line 83
def given_fields
  [@target.parent.id_field, @target.entity.id_field]
end

Private Instance Methods

populate_conditions(params) click to toggle source

Populate the list of condition objects @return [void]

# File lib/nose/statements/connection.rb, line 102
def populate_conditions(params)
  @source_pk = params[:source_pk]
  @target = params[:target]
  @target_pk = params[:target_pk]

  validate_keys

  # This is needed later when planning updates
  @eq_fields = [@target.parent.id_field,
                @target.entity.id_field]

  source_id = source.id_field
  target_id = @target.entity.id_field
  @conditions = {
    source_id.id => Condition.new(source_id, :'=', @source_pk),
    target_id.id => Condition.new(target_id, :'=', @target_pk)
  }
end
support_query_condition_for_path(path, reversed) click to toggle source

Get the where clause for a support query over the given path @return [String]

# File lib/nose/statements/connection.rb, line 123
def support_query_condition_for_path(path, reversed)
  key = (reversed ? target.entity : target.parent).id_field
  path = path.reverse if path.entities.last != key.entity
  eq_key = path.entries[-1]
  if eq_key.is_a? Fields::ForeignKeyField
    where = "WHERE #{eq_key.name}.#{eq_key.entity.id_field.name} = ?"
  else
    where = "WHERE #{eq_key.parent.name}." \
            "#{eq_key.parent.id_field.name} = ?"
  end

  where
end
validate_keys() click to toggle source

Validate the types of the primary keys @return [void]

# File lib/nose/statements/connection.rb, line 91
def validate_keys
  # XXX Only works for non-composite PKs
  source_type = source.id_field.class.const_get 'TYPE'
  fail TypeError unless source_type.nil? || source_pk.is_a?(type)

  target_type = @target.class.const_get 'TYPE'
  fail TypeError unless target_type.nil? || target_pk.is_a?(type)
end