Class: NoSE::Insert

Inherits:
Statement show all
Includes:
StatementConditions, StatementSettings, StatementSupportQuery
Defined in:
lib/nose/statements/insert.rb

Overview

A representation of an insert in the workload

Instance Attribute Summary

Attributes included from StatementSettings

#settings

Attributes included from StatementConditions

#conditions

Attributes inherited from Statement

#comment, #entity, #eq_fields, #graph, #group, #key_path, #label, #range_field, #text

Class Method Summary collapse

Instance Method Summary collapse

Methods included from StatementSettings

included

Methods included from StatementConditions

included, #populate_conditions

Methods inherited from Statement

#materialize_view, #read_only?, #requires_delete?, #to_color

Constructor Details

#initialize(params, text, group: nil, label: nil) ⇒ Insert

Returns a new instance of Insert.



10
11
12
13
14
15
16
17
18
# File 'lib/nose/statements/insert.rb', line 10

def initialize(params, text, group: nil, label: nil)
  super params, text, group: group, label: label

  @settings = params[:settings]
  fail InvalidStatementException, 'Must insert primary key' \
    unless @settings.map(&:field).include?(entity.id_field)

  populate_conditions params
end

Class Method Details

.parse(tree, params, text, group: nil, label: nil) ⇒ Insert

Build a new insert from a provided parse tree

Returns:



22
23
24
25
26
27
# File 'lib/nose/statements/insert.rb', line 22

def self.parse(tree, params, text, group: nil, label: nil)
  settings_from_tree tree, params
  conditions_from_tree tree, params

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

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



65
66
67
68
69
70
71
# File 'lib/nose/statements/insert.rb', line 65

def ==(other)
  other.is_a?(Insert) &&
    @graph == other.graph &&
    entity == other.entity &&
    @settings == other.settings &&
    @conditions == other.conditions
end

#given_fieldsObject

The settings fields are provided with the insertion



131
132
133
134
135
# File 'lib/nose/statements/insert.rb', line 131

def given_fields
  @settings.map(&:field) + @conditions.each_value.map do |condition|
    condition.field.entity.id_field
  end
end

#hashObject



74
75
76
# File 'lib/nose/statements/insert.rb', line 74

def hash
  @hash ||= [@graph, entity, @settings, @conditions].hash
end

#modifies_index?(index) ⇒ Boolean

Determine if this insert modifies an index

Returns:

  • (Boolean)


79
80
81
82
83
84
85
86
87
# File 'lib/nose/statements/insert.rb', line 79

def modifies_index?(index)
  return true if modifies_single_entity_index?(index)
  return false if index.graph.size == 1
  return false unless index.graph.entities.include? entity

  # Check if the index crosses all of the connection keys
  keys = @conditions.each_value.map(&:field)
  index.graph.keys_from_entity(entity).all? { |k| keys.include? k }
end

#requires_insert?(_index) ⇒ Boolean

Specifies that inserts require insertion

Returns:

  • (Boolean)


90
91
92
# File 'lib/nose/statements/insert.rb', line 90

def requires_insert?(_index)
  true
end

#support_queries(index) ⇒ Array<SupportQuery>

Support queries are required for index insertion with connection to select attributes of the other related entities

Returns:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/nose/statements/insert.rb', line 97

def support_queries(index)
  return [] unless modifies_index?(index) &&
                   !modifies_single_entity_index?(index)

  # Get all fields which need to be selected by support queries
  select = index.all_fields -
           @settings.map(&:field).to_set -
           @conditions.each_value.map do |condition|
             condition.field.entity.id_field
           end.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

    # Build conditions by traversing the foreign keys
    conditions = @conditions.each_value.map do |c|
      next unless graph.entities.include? c.field.entity

      Condition.new c.field.entity.id_field, c.operator, c.value
    end.compact
    conditions = Hash[conditions.map do |condition|
      [condition.field.id, condition]
    end]

    split_entity = split_entity graph, index.graph, entity
    build_support_query split_entity, index, graph, support_fields,
                        conditions
  end.compact
end

#unparseString

Produce the SQL text corresponding to this insert

Returns:

  • (String)


53
54
55
56
57
58
59
60
61
62
63
# File 'lib/nose/statements/insert.rb', line 53

def unparse
  insert = "INSERT INTO #{entity.name} "
  insert += settings_clause

  insert << ' AND CONNECT TO ' << @conditions.values.map do |condition|
    value = maybe_quote condition.value, condition.field
    "#{condition.field.name}(#{value})"
  end.join(', ') unless @conditions.empty?

  insert
end